Author : saradhi
Page : 1 Next >>
A primer on Pointers
Introduction to & and * operators
Consider the following C declaration.
int n=4;
This declaration tells the compiler to
Reserve in memory to hold an integer value.
Associate variable name ‘n’ with this memory location.
Store value 4 at the location.
Location name n
Value at location 4
Location number 4096
The computer has selected 4096 memory location to store the value of n. The location 4096 is a number not to be relied upon, because some other time the computer may choose a different location.
The important point is that n’s address in memory is a number.
We can print the address of n through the following program.
main()
{
int n=4;
printf(“Address of n = %u\n”,&n);
printf(“Value of n is %d\n”,n);
}
The output is
Address of n = 4096
Value n = 4
If you see the first printf() statement you observe that ‘&’ operator is used. The operator ‘&’ is called ‘address of operator’. The expression &n returns the address of variable n. In this case the address happens to be 4096.
The & operator when used with a variable name gives the address of the variable. On the other side of the coin we have another pointer operator ‘*’, also known as ‘value at address’ or ‘indirection operator’.
The ‘*’ operator when used with any ‘address’ gives the value at that address.
Consider the following example.
main()
{
int n=4;
printf(“Address of n = %u\n”,&n);
printf(“Value of n = %d\n”,n);
printf(“Value at address of n = %d\n”,*(&n));
}
The output would be
Address of n = 4096
Value of n = 4
Value at address of n = 4
Note that printing the value of *(&n) is same as printing the value of n.
Pointer expressions
We have now learnt that the address of any variable is also a number. And the expression &n returns the address of n. Hence the address (which is a number) can be stored in another variable saying
p=&n;
But p is not an ordinary variable like any other integer variable. It is a variable which contains an address of another variable ( n in this case).
Since p is a variable, the compiler must provide it space in memory.
Once again the following memory map would illustrate the contents of n and p.
Location name n p
Value at location 4 4096
Location number 4096 1600
As you can see, n’s value is 4 and p’s value is n’s address.
But we can’t use variable p, without declaring it. And since p is a variable which contains the address of n, it is declared as
int *p;
The int * conveys us that the value at the address contained in p is int.
The following program demonstrated the relationships we have been discussing.
main()
{
int n = 4;
int *p;
p=&n;
printf(“Address of n = %u\n”,&n);
printf(“Address of n = %u\n”,p);
printf(“Address of p = %u\n”,&p);
printf(“Value of p = %u\n”,p);
printf(“Value of n = %d\n”,n);
printf(“Value of n = %d”, *(&n));
printf(“Value of n = %d\n”,*p);
}
The output would be
Address of n = 4096
Address of n = 4096
Address of p = 1600
Value of p = 4096
Value of n = 4
Value of n = 4
Value of n = 4
If you don’t understand the program’s output of the meaning of expression &n, &p,*p and *(&p) it is advised to re read from the first.
Pointer declarations
int *i;
char *ch;
float *f;
Here i, ch, f are declared as pointer variables capable of holding address. Since addresses are always whole numbers, pointers are always whole numbers.
The essence is “Pointers are variables which contain addresses, and since addresses are always whole numbers, pointers would always contain numbers”
The declaration float *f does not mean that s is going to contain a floating point value. It means that f is going to contain the address of a floating point variable.
Similarly, char *ch means that ch is going to contain the address of a char value. Or in other words, the value at address stored in ch is going to be a char.
Pointer to pointer
We have learnt that a pointer variable contains the address of another variable. Now this variable itself could be another pointer. Thus, we now have a pointer which contains another pointer’s address. The following example should make this point clear.
main()
{
int =3;
int *j;
int **k;
j=&i;
k=&j;
printf(“Address of i = %u\n”,&i);
printf(“Address of i = %u\n”,j);
printf(“Address of i = %u\n”,*k);
printf(“Address of j = %u\n”,&j);
printf(“Address of j = %u\n”,&k);
printf(“Address of k = %u\n”,&k);
printf(“Value of j = %u\n”,j);
printf(“Value of k = %u\n”,k);
printf(“Value of i = %d\n”,i);
printf(“Value of i = %d\n”,*(&i));
printf(“Value of i = %d\n”,*j);
printf(“Value of i = %u\n”,**k);
}
The output would be
Address of i = 6480
Address of i = 6480
Address of i = 6480
Address of j = 3276
Address of j = 3276
Address of k = 7200
Value of j = 6480
Value of k = 3276
Value of i = 3
Value of i = 3
Value of i = 3
Value of i = 3
The following memory map will help you identify the relationships between i,j,k.
Location name i. j k
Value at location 4 4096 3276
Location number 6480 3276 7200
Observe how the variables i,j,k have been declared.
int i;
int *j;
int **k;
Here i is an ordinary int, j is a pointer to an int, whereas k is a pointer to a pointer to an int.
There is no limit on how far can we go on extending this defining. Possibly till the point we can comprehend it. And that point of comprehension is usually a pointer to a pointer. Beyond this, one rarely requires to extend the definition of a pointer. But just in case…..
Pointer jargon
Consider the following program fragment
int a=35;
int *b;
b = &a;
Which of the following statements are correct?
b contains address of int.
Value at address contained in b is an int.
b is an int pointer.
b points to an int.
b is a pointer which points in the direction of int.
Well, all the statements are correct. All the statements are trying to establish the same fact, that since b contains an address of int, its an int pointer. Similarly had b contained an address of a float, it would have been a float pointer. With the same argument if we have three pointer variables first containing address of an array, second containing the address of a structure and the third containing the address of a function then it would be appropriate to call these as an array pointer, a structure and a function pointer respectively.
Char, int and float pointers
Consider the following program
main()
{
int i, *ii;
char c, *cc;
flaot f, *ff;
i=32;
c=’A’;
f=3.14;
ii=&i;
cc=&c;
ff=&f;
printf(“Address of i = %u\n”,ii);
printf(“Address of c = %u\n”,cc);
printf(“Address of f = %u\n”,ff);
printf(“Value of i = %d\n”,*ii);
printf(“Value of c = %c\n”,*cc);
printf(“Value of f = %f\n”,*ff);
}
Output
Address of i = 1024
Address of c = 1400
Address of f = 1604
Value of i = 32
Value of c = A
Value of f = 3.140000
Note that in the printf()s the addresses of char, int and the float all have been printed using the format specifier %u. Observe that though the
Page : 1 Next >>