19

我是 C 编程新手,遇到了一个问题。
如果声明复杂,我发现了这个

int *daytab[13]; // daytab is an array of 13 pointers to int

这意味着daytab是数组的名称,并且数组的名称指向数组的第一个元素。数组名称与等指针操作不兼容daytab++(如果我错了,请纠正我)。

但我发现这段代码是用 Dennis Ritchie 写的

main(int argc, char * argv[]) {
    while( --argc > 0 )                    
        printf("%s%s",*++argv,(argc>1) > " " : "");

    printf("\n");
    return 0;
}

他们怎么能操纵argv?不是数组名吗?

4

7 回答 7

27

参数 char * argv[]衰减为指针,char ** argv。您同样可以将函数签名编写main()为:

int main(int argc, char ** argv)

argv您可以使用内的指针做任何您喜欢的事情main()argv++例如,只需将指针argv指向argv[1]而不是argv[0].

argv ---> argv[0] ---> "program"
          argv[1] ---> "arg1"
          argv[2] ---> "arg2"
           ...          ...
          argv[argc] == NULL
于 2013-05-21T09:21:06.047 回答
5

argv是一个数组char*。执行++argv意味着访问数组的下一个单元格。表示我们想要单元格的*值,而不是地址。

于 2013-05-21T09:25:56.800 回答
4

当程序启动时,它会在主函数中获取它的参数。这就是你通常写作的原因。

int main(int argc, char *argv[])

这仅仅意味着 argv 是指向 argc 所指示的尽可能多的参数字符串的指针(== 参数计数)。由于 argv 衰减为 char **argv 你也可以增加它,或者你可以像指针一样增加它。

因此,如果您想从命令行打印所有参数:

int main(int argc, char *argv[])
{
   for(int i = 0; i < argc; i++)
       printf("%s\n", argv[i]);

   for(int i = 0; i < argc; i++)
       printf("%s\n", argv++);

    return 0;
}
于 2013-05-21T09:24:55.377 回答
2

声明char *argv[]是一个指向 的指针数组(大小未定),char换句话说,是一个字符串数组。

并且所有数组都衰减为指针,因此您可以将数组用作指针(就像您可以将指针用作数组一样)。所以*++argv首先增加“指针”以指向数组中的下一个条目argv(循环中的第一次将是第一个命令行参数)并取消引用该指针。

于 2013-05-21T09:23:33.107 回答
2

参数声明看起来类似于数组的声明,但实际上(因为它是一个函数参数)它不是一个。C FAQ很好地解释了这一点。

于 2013-05-21T09:26:03.133 回答
0

argcargv是传递给程序主函数的参数。

argc在一个整数中保存参数的数量,并且argv是一个指向保存实际参数的字符串数组的指针。引用的每个元素argv都由空格分隔。

于 2013-05-21T09:23:13.133 回答
-1

这里所做的是指针运算。

指针并没有真正改变。

使用指针的地址,临时递增,然后用于输出。

因为操作符++放在argv前面,所以先取地址,然后递增,再解引用,得到这个地址后面的char*。

但改变的不是地址本身,而是 printf 将从中读取的偏移量。

好的 ?

于 2013-05-21T09:24:14.607 回答