Pointers
A variable is an area of memory that has been given a name.
For example, int x is an area of memory that has been given the
name x. The advantage of this scheme is that you can use the
name to specify where to store data.
For example, x=10 is an instruction to store the data value 10 in
the area of memory named x. The variable is such a fundamental
idea that using it quickly becomes second nature, but there is
another way of working with memory.
The computer accesses its own memory not by using variable
names but by using a memory map with each location of
memory uniquely defined by a number, called the address of
that memory location.
A pointer is a variable that stores this location of memory. In
more fundamental terms, a pointer stores the address of a
variable . In more picturesque terms, a pointer points to a
variable.
A pointer has to be declared just like any other
variable - remember a pointer is just a variable that
stores an address.
For example, int *p is a pointer to an integer.
Adding an asterisk in front of a variable's name
declares it to be a pointer to the declared type.
int *p , q; declares a pointer to an int and an int
variable, not two pointers.
Once you have declared a pointer variable you can
begin using it like any other variable, but in practice
you also need to know the meaning of two new
operators: & and *.
The & operator returns the address of a variable. You can remember this easily
because & is the 'A'mpersand character and it gets you the 'A'ddress.
For example int *p , q; declares p, a pointer to int, and q an int.
The instruction: p=&q; stores the address of q in p. After this instruction you can
think of p as pointing at q. Compare this to:
p=q;
which attempts to store the value in q in the pointer p - something which has to
be considered an error.
The second operator is the *.
If you place * in front of a pointer variable then the result is the value stored in
the variable pointed at.
That is, p stores the address, or pointer, to another variable and *p is the value
stored in the variable that p points at.
Example 1
int*p,q;
q=8;
p=&q;
printf("P is %d\n", p);
printf("q is %d\n", q);
printf("*p is %d\n", *p);
The * operator is called the dereferencing operator
and it helps not to confuse it with multiplication or
with its use in declaring a pointer.
There are only three basic ideas:
1.To declare a pointer add an * in front of its name.
2.To obtain the address of a variable use & in front of
its name.
3.To obtain the value of a variable use * in front of a
pointer's name.
Example 2
int *a , b , c;
b = 10;
a = &b;
c = *a;
This is a long winded way of writing c = b;
In General
Notice that if a is an int and p is a pointer to an int
then
a = p; is nonsense because it tries to store the
address of an int, i.e. a pointer value, in an int.
Similarly, a = &p; tries to store the address of a
pointer variable in a and is equally wrong!
The only assignment between an int and a pointer
to int that makes sense is:
a = *p;
Swap Shop:
Consider the following simple problem - write
a function which swaps the contents of two
variables.
That is, write swap(a,b).
function swap(int a , int b);
{
int temp;
temp = a;
a = b;
b = temp;
}
The only complication being the need to use a third
variable temp to hold the value of a while the value of
b overwrites it.
However, if you try this function you will find that it
doesn't work.
It will not change the values stored in a and b back in
the calling program.
The reason is that all parameters in C are passed by
value.
The solution to this very common problem is to pass
not the values stored in the variables, but the
addresses of the variables.
function swap(int *a , int *b);
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
Example
int main()
{
int rand1 = 12, rand2 = 15;
printf("rand1 = %p :rand2 = %p\n\n", &rand1, &rand2);
printf("rand1 = %d :rand2 = %d\n\n", &rand1, &rand2);
printf("Size of int %d \n\n ", sizeof(rand1));
int * prand1 = &rand1;
printf("Pointer rand1 %p\n\n", prand1);
printf("Pointer rand1 %d\n\n", prand1);
printf("Value stored in pointer = %d \n\n", *prand1);
}
Pointers And Arrays:
In C, pointers and arrays are basically the same
thing.
When you declare an array as:int a[10];
you are in fact declaring a pointer a to the first
element in the array.
That is, a is exactly the same as &a[0].
Hence a[i] is exactly equivalent to *(a+i) i.e. the
value pointed at by a + i .
In the same way *(a+ 1) is the same as a[1] and so
on.
In Summary
An array's name is a constant pointer to the
first element in the array that is a==&a[0] and
*a==a[0].
Array indexing is equivalent to pointer
arithmetic - that is a+i=&a[i] and *(a+i)==a[i].
When you pass an entire array to a function
then by default you pass a pointer.
This allows you to write functions that process
entire arrays without having to pass every
single value stored in the array - just a pointer
to the first element.
Example
int main(int argc, char *argv[])
{
int primeNum [] = {2,3,5,7} ;
printf("First Index = %d \n\n", primeNum[0]);
printf("First Index = %d \n\n", *primeNum);
printf("Second Index = %d \n\n", *(primeNum+1) );
return 0;
}
Example: write a function that will fill an array with random values
randdat(a,n) where a is the array and n is its size.
int randdat(int *pa , int n)
{
int i;
for ( i=0 ; i< n ; ++i)
{
*pa = rand()%n + 1;
++pa;
}
}
Task: Find out why the program below
is wrong.
void randdat(int *pa , int n)
{
for (pa = 0 ; pa < n ; pa++ ) *pa = rand()%n + 1;
}