Friday, October 3, 2008

C language Pointer arithmetic

Although a more rigorous description of pointer arithmetic is given later, we'll start with an approximate version that will do for the moment. Not only can you add an integral value to a pointer, but you can also compare or subtract two pointers of the same type. They must both point into the same array, or the result is undefined. The difference between two pointers is defined to be the number of array elements separating them; the type of this difference is implementation defined and will be one of short, int, or long. This next example shows how the difference can be calculated and used, but before you read it, you need to know an important point. In an expression the name of an array is converted to a pointer to the first element of the array. The only places where that is not true are when an array name is used in conjunction with sizeof, when a string is used to initialize an array or when the array name is the subject of the address-of operator (unary &). We haven't seen any of those cases yet, they will be discussed later. Here's the example.

#include
#include
#define ARSZ 10

main(){
 float fa[ARSZ], *fp1, *fp2;

 fp1 = fp2 = fa; /* address of first element */
 while(fp2 != &fa[ARSZ]){
         printf("Difference: %d\n", (int)(fp2-fp1));
         fp2++;
 }
 exit(EXIT_SUCCESS);
}
The pointer fp2 is stepped along the array, and the difference between its current and original values is printed. To make sure thatprintf isn't handed the wrong type of argument, the difference between the two pointers is forced to be of type int by using the cast(int). That allows for machines where the difference between two pointers is specified to be long. Unfortunately, if the difference does happen to be long and the array is enormous, the last example may give the wrong answers. This is a safe version, using a cast to force a long value to be passed:
#include
#define ARSZ 10

main(){
 float fa[ARSZ], *fp1, *fp2;

 fp1 = fp2 = fa; /* address of first element */
 while(fp2 != &fa[ARSZ]){
         printf("Difference: %ld\n", (long)(fp2-fp1));
         fp2++;
 }
 return(0);
}

No comments: