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.
To understand pointers, it may be worth understanding how normal variables are stored. If you disagree, Click here to move on.
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;
}
|
(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);
}
|
Length is 20
Address of Length is 0xF1
Please 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.
main()
{
int *Width;
}
|
(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);
}
|
Data stored at *Width is 34
Address of Width is 0xF1
Address stored at Width is 0xD1
|
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 */
}
|
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.
main()
{
char colour[]="red";
printf("%s \n",colour);
}
|
main()
{
char *colour="red";
printf("%s \n",colour);
}
|
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);
}
|
main()
{
char **DoublePtr;
}
|
#include |
Simple example passing a function pointer.
Example passing 'int' variables.
Example passing 'char' and 'char *' variables.
// declare array of function pointer of type void func(void)
void(*function_array[])(void) = {
case1function, // &case1function,
case2function, // &case2function,
...
};
void not_a_switch(int input) {
// execute whichever function is at array index "input"
function_array[input]();
// (*function_array[input])();
}
|