Techs and fun

Click here to edit subtitle

C and C++ programming


Introduction

There are two new C++ standards:  C++11/C++14. I advise you to get acquainted with it, better at Bjarne Stroustrup web site or at https://isocpp.org/ ( ISO C++ Standard )

This text was written back in 2005/2006, and still works to be introduced, although I keep updating it as much as possible.

Anyway, check news for updates and please VISIT  Bjarne Stroustrup web site. He may not be as fancy as James Gosling or Steve Jobs, yet he is ten thousand times smarter, important and humble!

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. C++ is actually a multipurpose language because it supports many different programming paradigms as generic programming, OOP, old and good procedural programming and meta programming.

Actually both C and C++ were created to make the work of a programmer easier, not just to satisfy a programming language designer's 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. 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 2011. 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, but I am not sure if it was updated to C11. ( Note I haven't used this book since 2006 ).

If you can only read Portuguese my suggestion is : be sure to check out and read everything at: UFMG C Course . If you can read English, it is probably easier to find free courses. 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 and structured paradigm first. ( Note I am not sure this course still exists still of today, but I know many people that started learning C from their course ).

C Usefull links:

  • 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.
  • C code snippets. Very, very usefull code listings that might be used and come at hand for professional jobs

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 complex 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 mostused 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 

The transition from C to C++ is not obvious, honestly, the only method I know to go through this process easily is to write code, laboriously and patiently.  A good C programmer will learn C++ easily, because, a good C programmer will enjoy the improvements  C++ has compared to C, and will feel motivated to go on.


C++ supports ( among others ) a paradigm named "Object Oriented Programming", which will make use of classes, encapsulation, polymorphism, etc. Again, be sure to use a book or tutorial that's ANSI C++ compliant otherwise you will find some troubles. 


Bjarne Stroustrup has a great tip to detect if a tutorial or book is compliant: if the author's main function return void, discard it. 


I highly recommend  http://www.cplusplus.com - which has been also updated to C++11/C++14.


One of the most powerful features in C++ are templates and STL. There are several data containers that can be used. Programmers need not to worry to implement linked lists or queues. Programmers already have at hand several algorithms for searching, sorting etc. The limits of STL these day lie where on how much you know it. Believe me, STL at this point, is faster than any code one can write.



How do I learn C++?

Books I recommend

I really recommend you C++ book "Sams Teach your self C++ in 24 hours", this is the book to start learning C++.  The other strong recommendation I have is "Programming Principles And Practices Using C++" by Stroustrup, which is a master piece in the same level of K&R.

After these two, Bjarne Stroustrup's 4th edition of "C++ Programming Language", which is by definition, the greatest and most important C++ canon. But I admit that is not a simply read and it is very expensive. and it works more effectively as a desktop reference ( and to scare Java programmers away ;-) ).

Stroustrup  has also released the excellent "A Tour Of C++" but that is not for novices too albeit rather simpler than the above, it is a very good reading for programmers that want to learn C++ with background in other languages like C or C#. 

I really like Scott Meyers "Effective C++" and "Effective Modern C++".

First of all, be sure of knowing all the procedural programming, e.g, 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, this actually very important.


To me the hardest part of C++ is operator overloading and at the same time this is my favorite feature of C++ and probably its most fascinating characteristic. 


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 and https://isocpp.org/ .


 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;
}



The STL strings, usually found under the header <strings>, and usually noted std::strings are very useful. They will save a lot of time and they are faster enough to make you to forget ANSI C NULL terminated strings.


The C++11 and C++14 new features not just make it C++ more appealing but faster and safer. Smart pointers, auto types, lambda functions, move constructors, etc.


A note for Brazilians:
I really recommend the quick reference guides written by Joel Saade: C++ and C++ And STL. These are quite GOOD books.