Pointers are at the heart of C. When you crack this subject, you have got the worst of C behind you. Before you tackle pointers though, you should get a grip on arrays.
What does the following program realy mean?
main() { int Length; } |
In my mind, it means, reserve enough storage to hold an integer and assign the variable name 'Length' to it. The data held in this storage is undefined. Graphically it looks like:
(Address) (Data) ---- ---- | F1 | <------- Length |----|----| | F2 | | |----|----| | F3 | | |----|----| | F4 | | ---------To put a known value into 'Length' we code,
main() { int Length; Length = 20; } |
the deciamal value 20 (Hex 14) is placed into the storage location.
(Address) (Data) ---- ---- | F1 | 00 <------- Length |----|----| | F2 | 00 | |----|----| | F3 | 00 | |----|----| | F4 | 14 | ---------Finally, if the program is expanded to become
main() { int Length; Length = 20; printf("Length is %d\n", Length); printf("Address of Length is %p\n", &Length); } |
The output would look something like this .....
Length is 20 Address of Length is 0xF1Please note the '&Length' on the second printf statement. The & means address of Length. If you are happy with this, you should push onto the pointers below.
An example of code defining a pointer could be...
Pointer definition.
A pointer contains an address that points
to data.
main() { int *Width; } |
A graphical representation could be...
(Address) (Data) ---- ---- | F1 | <------- Width |----|----| | F2 | | |----|----| | F3 | | |----|----| | F4 | | ---------So far, this variable looks the same as above, the value stored at 'Width' is unknown. To place a value in 'Width' you could code.
main() { int *Width; /* 1 */ Width = (int *)malloc(sizeof(int)); /* 2 */ *Width = 34; /* 3 */ } |
(Address) (Data) ---- ---- | F1 | 00 <------- Width |----|----| (Data) (Adress) | F2 | 00 | --------- |----|----| -------> 00 | D1 | | F3 | 00 | | |----|----| |----|----| *Width| | 00 | D2 | | F4 | D1 | ------- |----|----| --------- | 00 | D3 | |----|----| | 22 | D4 | ---------Statements 2 and 3 are important here:
2) The malloc function reserves some storage and puts the address of the storage into Width.
3) *Width puts a value into the storage pointed to by Width.
Unlike the Length = 20 example above, the storage pointed to by 'Width' does NOT contain 34 (22 in Hex), it contains the address where the value 34 can be found. The final program is...
main() { int *Width; Width = (int *)malloc(sizeof(int)); *Width = 34; printf(" Data stored at *Width is %d\n", *Width); printf(" Address of Width is %p\n", &Width); printf("Address stored at Width is %p\n", Width); } |
The program would O/P something like.
Data stored at *Width is 34 Address of Width is 0xF1 Address stored at Width is 0xD1 |
A pointer can point to any data type, ie int, float, char. When defining a pointer you place an * (asterisk) character between the data type and the variable name, here are a few examples.
main() { int count; /* an integer variable */ int *pcount; /* a pointer to an integer variable */ float miles; /* a floating point variable. */ float *m; /* a pointer */ char ans; /* character variable */ char *charpointer; /* pointer to a character variable */ } |
Pointers to arrays
When looking at
arrays we had a program that accessed data within a
two dimensional character array. This is what the code looked like.
main() { char colours[3][6]={"red","green","blue"}; }The code above has defined an array of 3 elements, each pointing to 6 character strings. You can also code it like this. Which is actually more descriptive because it indicates what is actually going on in storage.
main() { char *colours[]={"red","green","blue"}; }Graphically it looks like this:
colours *colours *(colours+2) **colours | | | | | | | | V V V | --- ----------- | | |---->| | | | | --- ----------- | | | | V | | | ----------------------- --------------->| r | e | d | | | | | | ----------------------- | | | | ----------------------- ---|-------->| g | r | e | e | n | | | ----------------------- | | ----------------------- -------->| b | l | u | e | | | ----------------------- A A | | | | **(colours+2) *(*(colours+2)+3) |
printf("%s \n", colours[1]); printf("%s \n", *(colours+1))will both return green.
Char Arrays verses Char pointers
What is the difference
between these two lumps of code?
main() { char colour[]="red"; printf("%s \n",colour); } |
main() { char *colour="red"; printf("%s \n",colour); } |
The answer is, NOTHING! They both print the word red because in both cases 'printf' is being passed a pointer to a string.
An array of 4 bytes is reserved and the text 'red' placed into the storage array. The contents of the array can be chaged later BUT on the left, the size of the array is fixed.
Here is a picture of the example on the right. The 'r' of 'red' is stored at address 10, the 'e' is at address 11 etc.
At this point it maybe worth looking at the malloc function.
int func(void *Ptr); main() { char *Str = "abc"; func(Str); } int func(void *Ptr) { printf("%s\n", Ptr); } |
Please note, you cant do pointer arithmatic on void pointers.
main() { char **DoublePtr; } |
A common use for these is when you want to return a pointer in a function parameter.
#include |
Pointers to functions
Pointers to functions can be used to create 'callback' functions.
An example of these pointers can be seen in the
qsort function.
Example passing 'int' variables.
Example passing 'char' and 'char *' variables.
function arguments.
Top | Master Index | Keywords | Functions |