tags:

views:

1769

answers:

3

I thought that if a c pointer pointing to a char array was incremented then it would point to the next element in that array. But when I tried this I found that I had to increment it twice. Trying the increment using sizeof(char) I found that adding the size of a char was too much so it had to be divided by two.

#include <stdio.h>

int main(int argc, char * argv[]){
   char *pi;
   int i;
   pi = argv[1];
   printf("%d args.\n",argc-1);
   printf("input: ");
   for(i=0;i<argc-1;i++){
      printf("%c, ",*pi);
      /*The line below increments pi by 1 char worth of bytes */
      //pi+=sizeof(pi)/2;
      /* An alternative to the above line is putting pi++ twice - why? */
      pi++;
      pi++;
   }
   printf("\n");
   return 0;
}

Am I doing something wrong? or am I misunderstanding the method of incrementing pointers?

+2  A: 

If you have a pointer ptr of type T* and you add N, then the pointer will be advanced by N * sizeof (*ptr) or equivalent N * sizeof (T) bytes. You simply forgot to dereference pi. So what you got with sizeof (pi) was the sizeof of the char*, but not the sizeof of a char. Your line was equivalent to pi+=sizeof(char*)/2; Pointers on your platform are 4 bytes big. Thus in effect you did pi+=2;. Write pi+=2 if you want to increment 2 times. Note that char has an sizeof of 1 by definition. You don't need to do sizeof (char), it is always 1.

Johannes Schaub - litb
+19  A: 

sizeof(char) is guaranteed to be 1, but sizeof(char*) isn't.

Nevertheless, your function only works by accident.

For example, try calling it with the following parameters:

abc defg

This will yield:

2 args.
input: a, c,

which is plain wrong. The problem is you are incrementing a pointer to the element 1 of argv instead of a pointer to argv.

Try this:

#include <stdio.h>

int main(int argc, char * argv[]){
   char **pi;
   int i;

   pi = argv + 1;
   printf("%d args.\n",argc-1);
   printf("input: ");
   for(i=0;i<argc-1;i++){
      printf("%c, ",**pi);
      pi++;
   }
   printf("\n");
   return 0;
}

This will print the first character of every argument:

2 args.
input: a, d,
phihag
+1  A: 

sizeof(pi) is returning the size of (char*), which is the type of pi (a pointer, probably two, four, or eight bytes). sizeof(char) will return 1.

However, another thing to understand is that whenever you increment a pointer by a number (e.g.: pi += sizeof(char); pi++; etc.) you are incrementing the pointer by the base size anyways. So:

int *ipointer = &int_array[0];
ipointer += 2;

will actually increment ipointer by 2 times sizeof int.

Another thing you seem to be doing wrong is pointing pi at the first argument, and then looping through all the arguments. If you want to loop through the arguments, try something like this:

for (i = 1; i < argc; i++) {
    pi = argv[i];
    // ... do something with pi
}
Avi
Robert Gamble
Thanks, Robert! You're right, of course; I have fixed the post.
Avi