You think you have understood pointers in C. And written some programs also using pointers. Then tell me what are these
1> int *a
2> int **a
3> int *a()
4> int (*a)()
5> int *a[5]
6> int (*a)[5]
7> int (*a())[5]
First one is obvious. All of us know a is a pointer to an integer.
<2> is again simple. a is a pointer to pointer to an integer
<3> Here a is a function whose return type is int pointer
<4> a is pointer to function which has no parameters and which returns an integer. Now you know how to write function pointers. Remeber to enclose the * along with function name in paranthesis.
<5> a is an array of 5 integer pointers
<6> a is pointer to an array of 5 integers. This is equivalent to a 2 dimensional array. Now do some home work. Compile a program with a function which takes a 2d array as a parameter (say
void print(int a[3][3])
with debugging enabled (as gcc prg.c -g). Start gdb and enter the function. Now ask the gdb whatis 2d array
gdb> whatis a
type int (*a)[3]
So gdb is telling you your parameter is a pointer to an array. This is one concept many of us misunderstand. Since 1d array gets converted into pointer when passed as a parameter, we think 2d array gets converted into pointer to pointer. NO, IT DOES NOT. It gets converted into a pointer to an 1d array, this pointer pointing to the first row. By incrementing the pointer, we get the second row.
<7> Here is a function which returns a 2d array. Now you will think how can a function return an array? No, the function is returning a pointer to an array, which is nothing but address of first row of the 2d array.
Let us write a function to return a matrix after doubling it and without modifying the original matrix
int (*doubleElements(int c[3][3])[3]
{
int d[3][3];
int i,j;
for(i=0;i<3;i++)
for(j=0;j<3;j++)
d[i][j]=c[i][j]*2;
return b;
}
Please note that int d[3][3] can also be written as int (*d)[3].
Now the more difficult part is how to accept the matrix returned by this function.
int a[3][3],b[3][3];
-------
-------
b=doubleElements(a);
-------
-------
Now tell me why this wont work. b is the base address of the array and hence can not be used on LHS. So let us rewrite it as
int a[3][3], (*b)[3];
Fine we are ready to test the program.Do we get the output. NO. We get some garbage values. Why?
Look at the life span of d. This array is valid as long as the function exists. And is popped out the moment you return from function. It is destroyed and we are returning this destroyed array.
Only way to overcome this problem is declare d as a static array.
static int (*d)[3];
Now static elements are not stored in data segment and hence are not destroyed when function returns.And now our prgram works!!!
Sunday, July 13, 2008
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment