增加C指针

6

我曾认为,如果一个指向char数组的C指针被递增,它将指向该数组中的下一个元素。但是当我尝试这样做时,我发现我必须递增两次。通过使用sizeof(char)进行递增尝试后,我发现添加char的大小太多了,所以必须除以2。

#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;
}

我做错了什么吗?还是我误解了指针递增的方法?
3个回答

20

char的大小被保证为1,但是char*的大小并不保证。

尽管如此,你的函数只是意外地可行

例如,试着使用以下参数调用它:

abc defg

这将产生:

2 args.
input: a, c,

这是完全错误的。问题出在您正在将指针递增到argv的第1个元素,而不是指向argv的指针。

尝试这个:

#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;
}

这将打印出每个参数的第一个字符:

2 args.
input: a, d,

4
如果您有一个类型为 T* 的指针 ptr,并且您添加了 N,那么指针将会向前移动 N * sizeof (*ptr) 或等效的 N * sizeof (T) 字节。您只是忘记对 pi 解引用。所以您使用 sizeof (pi) 得到的是 char* 的大小,而不是 char 的大小。您的代码等同于 pi+=sizeof(char*)/2; 在您的平台上,指针大小为 4 个字节。因此,实际上您执行了 pi+=2;。如果您想要增加 2 次,请写成 pi+=2。请注意,根据定义,char 的大小为 1,您不需要执行 sizeof (char),它总是 1。

3

sizeof(pi)返回的是pi的类型(char*)所占空间大小,即指针类型,可能是2、4或8字节。sizeof(char)将返回1。

然而,还有一件事需要理解,那就是每当你按照某个数字增加指针(例如:pi += sizeof(char); pi++;等),你都会自动增加基本大小。因此:

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

实际上,这将使ipointer增加2倍的int大小。

另一件你似乎做错了的事情是将pi指向第一个参数,然后循环遍历所有参数。如果你想要遍历参数,请尝试像这样:

for (i = 1; i < argc; i++) {
    pi = argv[i];
    // ... do something with pi
}

你的第一个代码示例是无效的,“&int_array”具有“指向int数组”的类型,与“指向int”的类型不兼容,你需要使用“&int_array [0]”或只是“int_array”。此外,在C中,sizeof(char)*定义为1,这一点是毫无疑问的,没有“可能性”。 - Robert Gamble
谢谢,罗伯特!你当然是对的;我已经修复了这篇文章。 - Avi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接