Friday, July 21, 2006

C and C++ programming

C and C++ tips





Introduction


Why this page is so simple layouted? Because I did want a
simple layout and wanted to focus simply at C and C++. I
basically gather C and C++ tips here and link them from my blog
main page.


Note: I don't want to overload a single page with links. I
just want to give you the good ones.


C is often called hard and complex and to a certain point, it
is complex I can't deny it. But, some will take more or less time to get it and
it is quite normal. Some facts regarding C/C++:



  • The greatest fear to come to novices are
    "pointers" and later anything that may use "pointers".

  • Assembly
    programmers just learn C easily and fast, at least I have seen
    it.

  • C++ on the other hand introduces a new paradigm, OOP, and it
    might be a little harder to get, but not an impossible task.




Actually both C and C++ were created to make the work of a programmer easier,
not just to satisfy a designer goal. Prior to the existence of C, if you wanted to allocate memory in Assembler, it'd be a real pain. C allows that you leave this task to the compiler. Within embedded systems you need to inform the compiler your memory profile but within Windows or Unix this is not required, but your job remains significantly easier.





The C Language


Before starting, if you could afford a C book I'd recommend
that you acquired "The C Programming Language", by Kernighan and
Ritchie, which were the creators of the language. Although, you
will find some outdated content ( the last edition of the book
came out in 89 ) as the ANSI C standard was last updated in 1999.
However, the book is fine. I don't have it though, but if you can afford and
plan to learn C, buy it.

There is an excellent book that recommend, which I take with me anywhere I go is "C The Reference Manual 5th Edition" written by
Samuel Harbison, which is careful enough to point the differences between all C versions.

If you can only read Portuguese my suggestion is : be sure to check out
and read everything at: UFMG C Course . This
is the only strict ANSI C ONLINE course in Portuguese. Many
others use "bizarre" code like:



void main(){
/* main in C has never returned VOID */
}


I need to quote Bjarne Stroustrup (actually not stricly like
this) "Avoid it because C programmers will find you ignorant".
Heh. I have seen experienced and excellent programmers
doing it, but to a proper vision it is better using the standard
right?


Old books, pre latest ANSI C standard, usually have:



main(){
/*OK the C compilers default to int*/
}


This is not that bad. As a matter of fact, another of my book
references in C is an old Microsoft C book by Kris Jamsa from a time
that the C99 ANSI standard was not even put into view ( 89 ), but
it teaches you good programming pratices and it follows good
ways to guide you.



If you can read english it is probably easier to find free
courses. Though the UFMG C Course will be
a real lost if you can't read Portuguese. There's a book named "C
How To Program" by the Deitels which also covers C++ and Java,
and I'd get it too. In fact, you can have their power point
presentations out of this book ( and many others ) from their web site.


In fact, C is the most used language on Embedded Systems
today, although some claim that it would be better to switch to
C++. Anyway, for a novice, it is better learning the procedural
structured paradigm first..


C Usefull links:



  1. Phil's C
    Course
    . It has a very good tutorial to learn C.

  2. Tom
    Torfs C Course
    . Tom Torfs wrote one of the best tutorials on C
    I know. With the advantage of being concise and covering all the
    language issues in 96 pages, that you can use later. I have
    printed out this and let a copy close to me and use it anytime I
    get in troubles. I think it is the best C reference available on the
    web but I would not start with this.

  3. C
    code snippets
    . Very, very usefull code listings that might be
    used and come at hand for professional jobs.

  4. Brian
    Kernighan
    . One of the creators of C.

  5. Dennis
    Ritchie
    . One of the creators of C.


  6. Stanford CS Education Library
    . Excellent reference for pointers, linked lists and C basics.


  7. Professor Peter Burden
    Despite a few outdated content regarding C, it's a very good
    reference. Search a little hard here and you will find many great reading
    tutorials from professor's Burden.


Which compiler to use?


There are many compilers available for free. I would use the
IDE Bloodshed Dev C++ that
uses the GCC version for WINDOWS as the compiler or the LCC compiler,
which is simple, easy to use and very powerfull. Many commercial
applications use the GCC
compiler
, which allows the coding for several microprocessors
and microcontrollers like x86, ARM, PIC, 8051, etc. If I were you
I'd stick with these 2 as they are simple and easy and allow ANSI
C! The same applies to learning C++. Except that the LCC compiler
only works for C. The LCC compiler is fine for C and WIN32S API
programming.



I have recently discovered the Quincy 2005 C/C++ compiler for windows which is an IDE for the above mentioned GCC on its Windows versions. LINUX and UNIX natively support the
GCC compiler so don't be afraid: you already have it!


Pointers?


If you're afraid of pointers, let me give you a few hints and
links. First of all think of pointers as an arrow pointing to a
memory location which's basically what a pointer is. When I have
troubles with pointers I consult Ted
Jensen's
tutorial which is very complete.


A pointer is nothing less than a variable that holds an
address. You could be wondering why? If you're passing a whole
struct to a function and will pass it by value ( i.e. not using
pointers ) the compiler will have to copy it all. For single
parameters this is not a trouble, but for huge arrays or huge
structs this might be a trouble. With a few experience you start
thinking about pointers as addresses and it is less scary with the
years.



int i; /*declares a variable of the integer type*/
int *y;/*declares a pointer*/
y = &i;/*y holds the address of the variable*/
int a[10];
y = a; /*you could've made y = &a[0] also */


In fact, the pointer points by copying the address of the
variable. If you increment a pointer, you just tell the compiler
to jump to the next memory value. If your pointer points to int
or float does not matter as it knows where to go. By the way, do
never try a "&yourPointer++", because it will cause you major
troubles. Either use:



*(yourpointer+1) = 2;

or



yourPointer++;.


Remember that & is the address and * is the content of the
pointer. Or & gets the address and * the value we want.


So, go fast to the Ted
Jensen's
tutorial if you are troubled with pointers. As a
matter of fact, he teaches a lot of tips, pratical ones,
especially if you are dealing with char types ( which is what you
usually do when dealing with tcp-ip, serial frames ).


Function pointers are also real hard to get IMHO, and it is
generally avoided. However, I had to use it. In C++, if you want
to have a generic function, you just use templates. In C, you
cannot use it, so you'll have to use function pointers. Do I need
to repeat that you should read the Ted
Jensen's
tutorial?


Say, you have such a function:



void Ovo( int * )
{
/**/
}


But you want to pass it a function. How to do it?




int function1( int y )
{
/**/
y = y + 20;
return y;
}
int function2( int y )
{
/**/
y = y + 30;
return y;
}


See that both functions have return types and parameters that
are compatible to our function pointer. It is then natural to
do:



int Ovo( int jaca, int (*functionptr)(int a ) )
{
/*Use functionptr as a shorthand for function1 or function2*/
int inside;
inside = functionptr( jaca );
return inside;
}

int main()
{
int a = Ovo( 2, function1 );
int b = Ovo( 3, function2 );

return 1;
}


The statement below is very complicated. As a matter of fact,
I have always a book at my side when using a function
pointer:



int Ovo( int jaca, int (*functionptr)(int a ) )/*...*/


Ovo is a function that returns a int. Its parameters are an
int value and a function pointer. Or, it gets a function that
returns an int and has an int parameter ( check function1 and
function2 ). Please note that we use the * operator in the
protoype/definition of the function and not when we actually use
the function. It's not required. Anyway, for further and better
explanations please check Lars
Haendel
's tutorial on function pointers.



Another tuff subject is dynamic allocation. Not because it's hard to understand,
I don't think so, but if do not deallocate memory, perhaps you'll be overloading
your memory capacities. C has many functions to allocate memory, and the most
used if malloc. It allocates N bytes from the heap, but you'll have to cast it
to your desired type as it returns a pointer to char. If malloc returns NULL,
you didn't get your goal.




#include <stdio.h>
#include <stdlib.h>


struct Example {
unsigned char item1;
int item2;
} ;

typedef struct Example MyStruct;/* always easier to declare a typedef to use
structs */

void GetAStruct( MyStruct * );/*prototype to a function that returns void
and receives a pointer to a struct*/

int main(int argc, char *argv[])
{
MyStruct ms;
MyStruct *mallocateds;
ms.item1 = 'A';
ms.item2 = 'B';
GetAStruct( &ms );
mallocateds = malloc( sizeof( MyStruct ) );
/*does not require the cast, I left it here because some compilers might
use it, and to prove that even me, can make NON C99 mistakes ;-)*/
if ( mallocateds != NULL )
{
mallocateds->item1 = 0x00;
mallocateds->item2 = 2;
}

free ( mallocateds );
system("PAUSE");
return 0;
}

void GetAStruct( MyStruct * s )
{
/*Do something with the struct you passed to
the function, use the -> operator to access its members */
s->item1 = 0x3A;
s->item2 = 2;

}






The C++ Language


C++ is often found harder to learn and I think that's probably
true. hehe ;-) A few people find easy to master C++, but the more
you learn the more you will find your self trying to learn more.
I like the Deitel's C++ book
"C++ How To Program". For other languages like Java, their book
is a little too much, but they reach the point for C++. It's good
also, because you also get a ton of information on UML. If you
are fortunate to learn C++ at college, your teacher may include
the UML part in the classes which will help you a lot. I also
enjoy Hebert Schildt's "C++ Complete Reference". You can next buy
the major reference on C++ that's "The C++ Programming Language"
by Bjarne Stroustrup, which is not indicated to novices at the
price of making them away from C++. It's a must have for C++
developers though.


C++ brings down a paradigm named "Object Oriented
Programming", which will make use of classes, encapsulation,
polymorphism and a bit of tricky subjects. Again, be sure to use
a book or tutorial that's ANSI C++ compliant otherwise you will
find some troubles. I can't count how many times, I had to tell
someone that he wasn't programming something compliant to the
standard and often I got stuff like "No, I am also right".


One of the best places to learn C++ is at Function X. I recommend that you
get a book to learn C++ though. Next, you can check good advanced
tutorials at the Stroustrup
page ( he was the creator of C++ ).


A lot of people think that Visual C++ or Borland C++ GUI
programming is part of the standard. However, this it not true. I
my self focus at embedded systems so this is not much my area.
Anyway, if you like this, check the Function X site. This misconception is really
annoying. Although Electrical Engineers may be working as programmers by programming
Windows, UNIX or whatever high level OS you wish to think, within the embedded
world it's more obvious to see Engineers writting firmware. The same thing
happens if you play guitars. Most people will say that you should also sing
while perhaps they don't know that guitar playing is a fine art that does not
necessarily includes singing. Programming is not necessarily high level GUI.
Look at this huge "world of small wonders" named embedded systems.



If you're a novice, avoid Bruce Eckel's books. They have a great quality in
terms of text, but it will confuse newcomers to C/C++. Although
they're free to download. I specially like the books, but I would
honestly not start C++ with them. Anyway, check them here.


How do I learn C++?


First of all, be sure of knowing all the prodecural
programming. Avoid GOTOs. Write modularized code, i.e, divide
your programs in modules ( make use of prototypes ), make them
easy to read. Eat pointers at breakfast. Next, take a deep
breath. Start by trying to find real world troubles and making
them C++ classes. Implement them, even if they're wrong. Submit
them to friends that know C++ already. Eat class design at lunch.
Next go for heritage and polymorphism. Heritage is the natural
way of reusing a object or class. Polymorphism allows you to
write less code when dealing with class hierarchies and also to
plan your classes at design. Dive down on the standard template
library.


In your programs now, you must make interactions between
objects, rather than passing parameters through functions. In
another words, you must model every class to mimic a real world
object and create a model that can be instantiated and that might
have the role you need.



One of the best features of the C++ language are its libraries and
Standard Template Libraries. If you need a reference to ( not to learn
it ) check this C++ reference.
It is a good thing to have a reference to these libraries. They're handy
enough to avoid you to write code that might've written, and for sure, better
than you could write.



C++ way of Dynamic allocation and the reference operator ( & )



In C you can pass a variable by reference by using pointers. In C++, you have
a different operator named &amp; or reference operator.



void function( int & i ){
//
}

int main(){

//...
int x = 10;// In C++ it's legal to define and initialize a variable
// inside the program outside the variable declaration
// place
function( x )// x is passed to the function by reference
// ...
return 0;
}



The & operator simply creates an alias. Another new usage in C++ is how
you allocate memory from the heap. In C, you should use malloc, calloc, etc,
and later you would have to free the memory with free. C++ allows you to
allocate memory from the heap using the "new operator". Say you have a class
named Aclass.




AClass c();// with this you call the constructor to instantiate c



By doing it, you're allocating memory from the stack. If you would like to
allocate from the heap, use the new operator:




AClass *c = new c();// The constructor is rather simple in this case
// but you can figure it out why, right? ;-)
// ...
// now that you don't need the object, deallocate it!
delete c;



Ever heard of objects talking to each other by sending messages? The very
functioning of good OOP means that you deal with objects that interact. Or,
class A sends a message to class B through a method. When you're designing
a class, have in mind that's necessary to deallocate every object you put
in the heap, so use the destructor.




class B{
public:
B();
~B();
private:
C *myc;
};

B::B(){
myc = new C();
}
B::~B(){
delete myc;
}




One of my favorite topics in OOP/C++ is heritage and polymorphism. Perhaphs,
because I took some time to digest the C++ way of doing it. We will start with
a class hierarchy as simple as possible:





class ClasseBase{
public:
ClasseBase( int = 0 );
ClasseBase( const ClasseBase & );
virtual void DoSomething() {}; //

};

ClasseBase::ClasseBase( int a ){
//
}

ClasseBase::ClasseBase( const ClasseBase & cb ){
//
}


class ClasseDerivada: public ClasseBase {
public:
ClasseDerivada( int = 0, int = 0 );
void DoSomething(){ cout << 1; };
}




After having, a derivation set, we need to implement it. Next,
you need a class that deals with these classes. This class must use
polymorphism to access a class. In terms of OOP, we might say that
this class will receive a message from another class.




class UsaHierarquia{
public:
UsaHierarquia( ClasseBase * cb );
~UsaHierarquia();
private:
ClasseBase *cdl;
};




In the constructor we need to pass a reference to the object and we need a
pointer to it inside the class. There are no methods here to use the class
that is passed to UsaHierarquia, but you could use the pointer to access it.





UsaHierarquia::UsaHierarquia( ClasseBase * cd ){
//
cdl = new ClasseDerivada( 2 , 2 );
}

UsaHierarquia::~UsaHierarquia(){
//
delete cdl;
}



Thank God that we can write destructors. In a real system, check the possibility
of having all your memory taken and allocated after use. In embedded systems
this is nearly dead, so deallocate every object off the heap.



Take note that I used just two very simple and nearly empty classes with a
purpose: do not confuse you as a few C++ books used to do for me. We have two
classes where one of them is derived from the other. We can say that there's a
relationship between them, but the base class cannot be instantiated.
It allow us to make our refinements in our derived classes as our goals need.



A final word, or many of them ;-)


It doesn't matter that people only talk about C# or Java.
Apparently C and C++ are disappearing. In Brazil, I am afraid to
say that's nearly true. Besides a few companies that still write
embedded software, most of what is called development is made for
web or for GUI on Windows. In the USA, it seems that a lot of
people still care for C or C++. For example, Motorola has put
great efforts to help developers to migrate from Assembly to C.
Ok, certain areas require Assembly routines, but larger systems
are a mess if written in Assembly. Today, it's not hard to find a C compiler
to your target processor, specially if you see the GCC project growing up
everyday allowing more processors to be programmed in C. Assembly is harder
to program I admit, but C is clearer and fast. Check out the
GCC project page for further information.





Bio: Even if I work 8 hours a day programming in C, I really love to talk,
read, write about C/C++, digital electronics/hardware, RTOS and scientific extrapolation
on free time. When I am not with my wife and kids ( most of time of course! )
I either watch a film, listen to music or play bass guitar. I have validated this XHMTL page but when I
uploaded it to geocities they added a few NON COMPLIANT lines of code. HEHEHEHEHHE I
don't mind actually but I prefer to follow standards.
Check W3Schools for free courses on
XHTML, CSS and DHTML. I enjoy "filet a parmeggiana" steaks, sea food and nestea-like cold ice drinks. Who cares anyway ?!!!!! :-)










Daniel Vasconcelos Gomes

zlogdan at gmail dot com

1 comment:

Daniel Swan said...

Nice post there my friend :)

Picked up a couple of links that look very useful.

I still have a book on C and another on C++ that I have never actually got through and feel I should someday, in between my half hearted attempts to learn C# and Java.

Maybe I should just go back to C. Get all those fundamentals down. Get rid of all my bad Perl habits lol.