simple, actually!
seriypshick said:
I find this topic very confusing. Can someone point me in the right direction? A good tutorial would be nice.
Thanks, Serg.
Apart from the great recommendation of "Practical C" by Steve Oualline, I would recommend the standard C book "The C Programming Language" by Kernighan and Ritchie. It's concise and may probably take a couple of readings to grasp what it conveys - but it's the best resource for the C language.
A brief guide (although it may appear cryptic):
* A normal variable holds a value that you use in the program - so an int holds an integer value, a char holds a character value and so on
* A pointer variable holds the address of another variable (or memory location) - it DOES NOT hold a value similar to other types. So an int * actually holds the address of ("points to") an integer, a char * actually holds the address of ("points to") a character and so on.
* Since a pointer only holds the address and not the value itself, you have to "dereference the pointer" to get the value it's pointing. Dereferencing is done by putting a * before the name of the variable. Eg: *p = 10;
* The "data type" of a pointer is the data type of the variable it will point to. So an int * will point to an integer and not a character (ok, it can point to anything but by default it will behave as if what it points to is an integer). Dereferencing an int * will give an integer, deferencing a char * will give a character and so on.
* It's necessary to initialize a pointer before using it (otherwise you might end up accessing some random location that's not allowed by the OS, causing the program to crash for seemingly no reason).
* A pointer is usually initialized by
---- assigning the address of an existing variable to it (using the & operator, like in p = &a; )
OR
---- by assigning the address of a memory block that's dynamically allocated using malloc or similar routines (like in p = malloc(10); )
* Pointers are restricted in the operations they can take part in, since they hold memory addresses. For instance, multiplication of two pointers doesn't make sense (what do you get by multiplying two addresses???). But addition or subtraction of integers to/from pointers are allowed - this would help move the pointer to point to an address after or before what it was pointing to. Eg: p = &a + 1 ---- this makes p point to the next location of the same data type as a (following the location where a is located).
* Pointer arithmetic is useful to traverse through arrays - incrementing or decrementing a pointer can make it refer to different elements of an array.
* You can "cast" a pointer to make it behave as a pointer of another data type. So an int *p can be made to give a character by saying "*(char *)p" - the first * is for dereferencing, and the (char *) is to temporarily cast it to a char pointer. Casting pointers to different data types can be used to solve problems in different ways.
* You can have pointers to pointers - a pointer to a pointer will hold the address of a pointer. This can be extended infinitely - you can have a pointer to a pointer to a pointer to a pointer....but it's highly complex to imagine what such a variable would actually be used for in the real world once you cross three levels.
If your head doesn't hurt by now, refer to "The C Programming Language" by Kernighan and Ritchie - it has a very good section on pointers as well as efficient use of them!