What is a Pointer?
A pointer is a variable which contains the address in memory of another variable. We can have a pointer to any variable type.The unary or monadic operator & gives the ``address of a variable''.
The indirection or dereference operator * gives the ``contents of an object pointed to by a pointer''.
To declare a pointer to a variable do:
int *pointer;
1st example: x value is 1 and address is 100
in ip we assign the address of x into ip.
2nd example: *ip means getting the value at the address
contained by ip . so ip has 100 and at that address it has value 1
so that value is assigned to y.
3rd example: we assign the value of ip that is 100 to x so x now has 100.
4th example: now this is tricky so try to understand this carefully.
*ip means assigning the value at the address contained by ip (100)
so at the address assign value 3 .
now the memory address 100 the value is 3.
as x's address is 100 so now x value also is now 3.
We can do integer arithmetic on a pointer:
float *flp, *flq; *flp = *flp + 10; ++*flp; (*flp)++; flq = flp;NOTE: A pointer to any variable type is an address in memory -- which is an integer address. A pointer is definitely NOT an integer.
The reason we associate a pointer to a data type is so that it knows how many bytes the data is stored in. When we increment a pointer we increase the pointer by one ``block'' memory.
So for a character pointer ++ch_ptr adds 1 byte to the address.
For an integer or float ++ip or ++flp adds 4 bytes to the address.
Consider a float variable (fl) and a pointer to a float (flp) as shown in
Pointer Arithmetic Assume that flp points to fl then if we increment the pointer ( ++flp) it moves to the position shown 4 bytes on. If on the other hand we added 2 to the pointer then it moves 2 float positions i.e 8 bytes as shown in the Figure.
Pointers and Arrays
Hint: think of array elements arranged in consecutive memory locations.Consider the following:
int a[10], x; int *pa; pa = &a[0]; /* pa pointer to address of a[0] */ x = *pa; /* x = contents of pa (a[0] in this case) */
Arrays and Pointers
To get somewhere in the array using a pointer we could do:
pa + i a[i]
There is no bound checking of arrays and pointers so you can easily go beyond array memory and overwrite other things.
For example we can just type
pa = a;
instead of
pa = &a[0]
and
a[i] can be written as *(a + i).
i.e. &a[i] a + i.
We also express pointer addressing like this:
pa[i] *(pa + i).
However pointers and arrays are different:
- A pointer is a variable. We can do
pa = a and pa++. - An Array is not a variable. a = pa and a++ ARE ILLEGAL.
Multidimensional arrays and pointers
We should think of multidimensional arrays in a different way in C:A 2D array is really a 1D array, each of whose elements is itself an array
Hence
a[n][m] notation.
Array elements are stored row by row.
Consider int a[5][35] to be passed in a function:
We can do:
f(int a[][35]) {.....}
or even:
f(int (*a)[35]) {.....}
These both are same.
We need parenthesis (*a) since [] have a higher precedence than *
So:
int (*a)[35]; declares a pointer to an array of 35 ints.
int *a[35]; declares an array of 35 pointers to ints.
Understand the above eg, carefully as this might be confusing.
char Aname[10][20];
Aname has 200 elements.
access the elements via
20*row + col+bas+address
in memory
char *name[10];
name has 10 pointer elements.
each pointer element can point to arrays of different length.
Consider the below :
char *name[] = { ``no month'', ``jan'', ``feb'', ... }; char Aname[][15] = { ``no month'', ``jan'', ``feb'', ... };
2D Arrays and Arrays of Pointers
name points to array of 13 elements which in turn hold reference (address ) 13 arrays.
no month\0 is one array that name[0] is pointing to.
similarly jan\0
(Notice Each string ends with '\0' . String is an array of char type )
Consider the below example:
What happens when we declare a one dimensional array in memory.
in A[5]
mem location:
200 204 208 212 216
-----------------------------------------
|2 | 4 | 6 | 8 | 10 |
-------------------------------------------
^ ^ ^ ^ ^
| | | | |
A[0] A[1] A[2] A[3] A[4]
contiguous block of memory
integer is stored in 4 bytes ( block of four bytes)
int *p = A;
address of array A will stored in p so aestrick upon a variable is used to hold
value of address.
now we can by using d-referencing technique get other elements of the array A.
eg:
print( p ) // Will give address of Array A 1.e 200
print( *p ) // will print the value at 200 memory location i.e 2
// Above is what is called d-referencing a pointer using * with //address will give us the value at that address
print(*(p+2) )// will print 6 . This addition of 2 to integer pointer variable
//means we will hop two times from starting aadress
// in address if we add anything suppose 2 or 3 what it does is
//adds 2*(no of bytes occupied by one element) here 4 bytes
// occupied by each int element so 2*4 = 8
// 200+8 is 208 so p+2 is 208 and *(p+2) is the value at
//208 i.e 6/
C gives us the flexibility of using array name instead of pointer variable.
Remember: Name of the array returns the address to the first element in the array.
So print( p ) is same as print(A)
similarly
*A will print the value at A i.e 2.
*(A+2) will give us 6.
*(A+i) is same as A[i] .( where i being any number in the range of array i.e
0 to n , n being the length of array )
A+1 is same as &A[i] . both will give us the address of the i th element.
Imp thing to note is
int *p;
we can do p = A;
but not
A=p; //will give compilation error
Two dimensional array.
int B[2][3];
here we are creating arrays of array
in this case we are creating 2 one dimensional array of length 3.
B[0] -- an array of 3 elements so will occupy 3* 4 bytes( 4 because
each int element will occupy 4 bytes each ) so 12 bytes tot
B[1] -- another array of 3 elements.
400 412
-----------------------------------------
400 404 408
| 2 |3 | 4 | 5 | 6 | 7 |
^
B[0][0]
-------------------------------------------
^ ^
| |
B[0] B[1]
int *p = B // compilation error as B will return pointer to a 1D array.
int (*p)[3] =B ;// This now correct as p will be able to hold what B returns
// that is pointer to a 1 D array of 3 elements.
print(B); // same as &B[0] that is 400
print(*B); // same as &B[0] or &B[0][0] 400
print(B+1); // B returns array of 3 integers
// adding 1 to that is like
// hoping the 3 elements
// B is 400 add one is
// hoping 3 int elements
// 4*3 =12
//412
/// Don't get confused as this is a 2d array
// remember as b returns array of 3 so adding one to B will
//let us hop 1st row and go to next row.
print( *(B+1)); // same as B[1] or &B[1][0] ,B+1 returns a pointer to the
// 1 d array of 3 elements as shown above so 412
// *(B+1) is similar to int *p = &B[1][0]
print (*(*B+1)) ; // *B is same as &B[0] as we see above
// adding one to that is same as adding 1 to memory address
// of &B[0][0] which will give 404
// Now *(&B[0][0]) which is we are dereferencing address 404
/// it will give us 3.
print ( *(B+1)+2) // same as &B[1][0] add 2 to it is 412 + 2*4 ( int elements
// has 4 bytes == 420
Point to remember
for a 2-d array
B[i][j] where i and j are some indices in the array is same as
B[i][j] == *(B[i]+j)
B[i][j] == *(*(B+i)+j)
courtesy: http://www.cs.cf.ac.uk/Dave/C/node10.html