What is a pointer
- A pointer is another variable that stores the location in memory where something is located.
int *a;
int b;
b = 8;
a = &b;
Take this example, when defining a you are telling us it is a pointer to an int by using int *. After you give b a value you are telling a that its new value is the location of b, by using the ampersand you are referring to b. Because a points to the location b is, you can get the value at the location pointed to by a.
c = *a;
Now c is the same value as b. Note the different use of the *. When defining a variable it is a way of telling C that you are creating a pointer. But when used on a pointer in this manner it is in fact dereferencing it. That is a refers to b, but *a is b. So it is just copying the value of b into c.
What can a pointer be used for
- A pointer can be used to provide functions with a way of changing a variable.
void changeme(int a)
{
a = 5;
}
int main()
{
int b;
b = 4;
changeme(b);
return 0;
}
What happens in that code? You give b a value of 4. You then call changeme() to change it to 5 right? Wrong. In C when you give changeme() a parameter of b it is in fact copying it. changeme() can in fact change its parameter to anything it wants and you will have no effect by it. What is the solution? Tell it where b is!
void changeme(int *a)
{
(*a) = 5;
}
int main()
{
int b;
b = 4;
changeme(&b);
return 0;
}
See what we have done here? We have given changeme() a pointer to b instead of just copying b. Notice the new use of * in changeme() > it is just like a variable declaration inside a function. The tricky part comes inside changeme(). (*a) = 5 that is the value at which a points to is now equal to 5. So after the call to changeme(), b is now 5.
Pointer arithmetic
Here is a rather bad example on how you can increment or decrement the value of pointer just like any numeric variables in C. The for loop uses a pointer on ptrStr to move through the string.
First the loop affects ptrStr to the address of the first character of myStr. After this, it's legal to get the value pointed by ptrStr using *ptrStr. Before the next loop, ptrStr is increment by 2 * sizeof(char). This is important because if ptrStr pointed on an array of integer, the increment would be different (see next example).
char myStr[] = "T h i s i s a r a n d o m t e x t";
char * ptrStr;
for (ptrStr = SomeString; *ptrStr != '\0'; ptrStr += 2)
printf("%c\n", * ptrStr);
Unknowingly, I made this example a good demonstration of the danger of pointer arithmetics. If you look closely at that loop, you'll see that if the length of the string is odd, the program will simply step over the NULL character indicating the end of the string and will continue to read past the memory allocated to myStr until it finds another '\0' at the right place. This may cause a corruption of data in other regions of the program (if you write to the memory). In Operating Systems that use a single address space for all programs (DosOs, MacClassicOs) it may cause other programs to crash (again if you write to the memory). In an Operating System that uses VirtualMemory, a Segmentation Violation may occur if you read into regions that are marked as unreadable by the kernel.
Actually, I did not notice a crash when I ran this program. It simply displayed a bunch of garbage characters after myStr text and stopped after a while. But believe me, I may not be that lucky next time
Here is another hopefully more useful example:
long myLong = 123456789;
short * ptrInt;
ptrInt= &myLong;
printf("%x\n", *ptrInt);
ptrInt++;
printf("%x\n", *ptrInt);
This code is used to display the 2 2 bytes integer included in 1 single 4 bytes. See how ptrChar++ increments the value of ptrChar by 2 bytes because it's type is short *.
Notice that this code is valid too:
long myLong = 123456789;
short * ptrInt;
ptrInt = &myLong;
printf("%x\n", ptrInt[0]);
printf("%x\n", ptrInt[1]);
Because pointers can be treated just like arrays.
Pointers and Arrays
An array is technically a pointer. In fact, the above two examples would most likely compile to the same assembly code. One might call an array a "pre-initialized pointer". A pointer is just a cell in memory that points to an address. An array is a constant pointer to some point in memory which is already initialized to a set amount of elements. Anything you can do with an array you can do with a pointer, and vice-versa (except for changing the pointer itself).
I'm short on explanations on why pointers = array. It would be nice if someone could complete that. -- FrancoisDenisGonthier
Writing ptr[n] is equivalent to *(ptr+n). I'd rather say that "a array" is a special kind of pointer, i.e. array in char array[100] behaves like a char* const ptr. Still looking for a better explanation though - MarkusB
A C array is not a pointer, because there are no values of array type, but there are values of pointer type. For instance, you can assign to a variable of pointer type, but not one of array type. The official terminology is that an array variable "decays to a pointer" when you use it in an expression. -- AdamChlipala
