我有这个小程序:
#include <stdio.h>
int main() {
char *argv[3] = {{"abc"}, {"def"}, {"ghi"}};
printf("%c\n", (*++argv)[1]); //error. I wanted to print 'b'
printf("%c\n", *++argv[1]); //prints e
return 0;
}
错误消息:
error: cannot increment value of type 'char *[3]'
printf("%c\n", (*++argv)[1]);
我想将argv
增加到b
。我直接从K&amp; R的C编程语言中使用了这个用法(*++argv)[i]
,他们在第117页有一个例子,就像我一样递增argv
。他们还指出(*++argv)[0]
是指向字符串中第一个字符的指针,而*++argv[0]
递增指针argv[0]
。确实(*argv)[1]
将打印b
而*argv[1]
将打印d
。然而,以某种方式递增(*++argv)[0]
只会导致错误。
答案 0 :(得分:3)
首先,这个:
char *argv[3] = {{"abc"},{"def"},{"ghi"}};
正如其他人所指出的那样:
char *argv[3] = {"abc", "def", "ghi"};
其次,你所做的并不是K&amp; R书所做的。
数组名称就像它们是常量指针一样,因此您不能像尝试使用argv = argv + 1
(++argv
的扩展版本)那样更改它们。
但是本书通过命令行将argv
传递给main ,所以当char* argv[]
进入main时,衰减到指向指针(char**
)的指针然后,是的,如果将字符串作为命令行参数传递,则可以使(*++argv)[1]
工作。
尝试在main中创建一个伪造的argv
,就像你一样,并将其相关地址与传入main via命令行的真实argv
相关的地址进行比较。
您会看到一个是char**
而另一个是char* array
:
#include <stdio.h>
int main(int argc, char* argv[])
{
printf("argv: %p\n", argv);
printf("&argv[0]: %p\n", &argv[0]);
printf("&argv: %p\n\n", &argv);
char* bogus_argv[] = {"abc", "def", "ghi"};
printf("bogus_argv: %p\n", bogus_argv);
printf("&bogus_argv[0]: %p\n", &bogus_argv[0]);
printf("&bogus_argv: %p\n\n", &bogus_argv);
printf("%c\n", (*++argv)[1]); // prints 'b'
printf("%c\n", *++argv[1]); // prints 'e'
return 0;
}
运行:./program abc def ghi
我机器上的输出:
argv: 0x7ffcde5aca98
&argv[0]: 0x7ffcde5aca98
&argv: 0x7ffcde5ac9a0
bogus_argv: 0x7ffcde5ac980
&bogus_argv[0]: 0x7ffcde5ac980
&bogus_argv: 0x7ffcde5ac980
b
e
答案 1 :(得分:2)
来自K&amp; R的示例引用argv
定义为函数main
的第二个参数。您的定义不同,您定义了一个包含3个字符串指针的数组,而函数参数是指向此类数组的指针。
函数原型语法有些误导,因为相同的语法用于不同类型的对象。有些人更喜欢这种语法:
int main(int argc, char **argv) {
...
}
使用这个原型,argv
(指向char
指针的指针)的性质更明确地出现,但许多程序员更喜欢等效的char *argv[]
语法来强调argv
{1}}指向数组指针而不是单个指针。
argv
是您代码中的数组,您无法递增它:这解释了为什么您收到printf("%c\n", (*++argv)[1]);
的错误。
您可以通过以下方式更改程序:
#include <stdio.h>
int main(void) {
char *argument_array[4] = { "abc", "def", "ghi", NULL };
char **argv = argument_array;
printf("%c\n", (*++argv)[1]); // will print 'e' instead of 'b'
printf("%c\n", *++argv[1]); // prints 'h', not 'e'
return 0;
}
另请注意,您应该删除初始值设定项中的冗余{}
,并且++
运算符是前缀,因此输出不完全符合您的预期。
答案 2 :(得分:1)
你犯了一个错误的声明。它应该是一个警告。它应该是
char *argv[3] = {"abc","def","ghi"};
内部大括号不是必需的,因为字符串是char指针,因此是“数组”。
您可以声明第二个指针变量并将其分配给argv:
char ** p;
p = argv;
然后增加p。
最后但并非最不重要的是,如果你想先打印b然后再打印e,你必须将“++”运算符放在变量后面。否则它会在评估之前递增指针,你会打印e和h。