The Joy of
Programming Understanding Pointers in C
S.G. Ganesh
Pointers are the forte of C, are the most difficult to master, and programming with them is prone to errors. But pointers are fun too! This month, we’ll look at some puzzles to understand some interesting aspects of pointers in C. In the following programs, assume that necessary header files are included. Q1. Will this program result in an assertion failure? int main() {
assert(sizeof(void *) == sizeof(int *));
assert(sizeof(int *) == sizeof(int **));
}
Q2. What will this program print? int main() { int iarr[10]; int *i = &iarr[2], *j = &iarr[5]; int *k = i + j; int diff = j – i; printf(“%d”, diff); }
Q3. Will this program work? int main() { int i = “C is often unpredictable!”; printf(i); }
Q4. What does the following program print? int main() { char string[10]; printf(strncpy(string ,”Joy of C”,3)[3] = ‘\0’); }
Q5. What does this following program print? int main() {
// assume that address of i is 0x1234ABCD
int i = 10; int * ip = &i; int **ipp = &&i; printf(“%x, %x, %x”, &i, ip, *ip); }
Well, they don’t seem too difficult, do they? It is too soon
to decide, so check the answers first: A1. This program will run fine without an assertion failure. Sizes of all pointer types are equal! This might be surprising to many programmers, but it is easy to understand. Pointers signify an address. In general, for a given implementation, the storage space required for storing an address is the same, irrespective of the type of pointer used. A2. This program results in a compiler error for the expression ‘i + j’. Why? Pointers signify the address and it is illogical to add two addresses. However, you can add an integer value to an address; for example, an array-based address is a pointer and to locate an array element, it is enough to simply add an integer to that address. Pointer subtraction is allowed; in this case, for example, ‘i – j’ indicates the number of array elements between them, which is equivalent to the expression (&iarr[5] - & iarr[2]), and is always 3, irrespective of the size of int. A3. Old C compilers or modern C compilers in K&R C mode (which refers to pre-ANSI C -- the original C language defined by Dennis M. Ritchie) do not have strong type checking and, hence, they will compile this fine. In the underlying implementation, if the size of int and the size of the pointer are the same, then there is no problem in storing the address of the string literal in integer i. printf is a dumb routine and it will interpret the first argument as a string (in fact, i has an address of a string literal). So, this program might compile and print: “C is often unpredictable!” A4. Yes, this program will print “Joy”! Note that strncpy returns a char* which is the address of the copied string. Here, strncpy copies three characters and returns that string. Then, we do indexing on that returned char* and put the null terminator ‘\0’ for that string in the index position [3]. The printf gets “Joy” as the argument and prints it. A5) This program results in a compiler error for the expression ‘&&i’. The ‘&&’ operator is a logical ‘and’ operator and requires two operands. Ignoring this syntax issue, the more important problem is that the attempted expression is illogical. It is possible to take ‘address of i’ with &i; but address of ‘address of i’ cannot exist! By: S G Ganesh is a research engineer at Siemens (Corporate Technology), Bangalore. His latest book is ‘60 Tips on Object Oriented Programming’ published by Tata McGraw-Hill in December 2007. You can reach him at
[email protected] www.openITis.com
cmyk
|
LINUX For You
|
february 2008
127
128
february 2008
|
LINUX For You
|
www.openITis.com
cmyk
www.openITis.com
cmyk
|
LINUX For You
|
february 2008
129