"char * argv[]" 是什么意思?

23

我是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?难道不是数组的名字吗?


这是一个指向(char)数组的指针,该数组包含系统传递给您的应用程序的所有参数,argc包含相同数量的计数。 - Hanky Panky
1
在包含 printf 的那一行中,最后一部分不应该是 (argc>1) ? " " : "" 吗?独立的 '>' 似乎不正确。对我来说,它看起来像是要在打印参数时在它们之间放一个空格,但是在最后一个参数后面没有空格。 - Bob Jarvis - Слава Україні
1
我非常震惊,四年过去了,对于解释C变量声明的顺时针螺旋法则仍然没有任何参考。哦,等等... :-) - Bob Jarvis - Слава Україні
1
一个解释C语言变量声明的绝佳资源:http://cseweb.ucsd.edu/~ricko/rt_lt.rule.html - Ambareesh
7个回答

31

参数 char * argv[] 会衰减为一个指针,char ** argv。你同样也可以使用下面的函数签名来定义 main() 函数:

int main(int argc, char ** argv)

main()函数内部,您可以随意使用指针argv,例如argv++只是将argv指向argv[1]而不是argv[0]

argv ---> argv[0] ---> "program"
          argv[1] ---> "arg1"
          argv[2] ---> "arg2"
           ...          ...
          argv[argc] == NULL

1
那么为什么在 char argv[] 的情况下不这样做呢? - akash
4
argv[] 表示一个字符串,而 *argv[] 表示多个字符串。 - Devolus
1
非常感谢!!明白了!!这是因为它是一个函数参数!! :) - akash
@akash 在 argv[argv] ---> NULL - Grijesh Chauhan
2
@BobJarvis 是的,谢谢。我的意思是 argv[argc] ---> NULLargv 是以 NULL 结尾的 字符串 数组。 - Grijesh Chauhan

5

当程序启动时,它会在main函数中获取参数。这就是为什么你通常会写:

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

1
请注意,此代码与OP发布的代码不执行相同的操作。请仔细注意原始代码中的预增量和预减量运算符的使用以及运算符优先级的影响。分享并享受。 - Bob Jarvis - Слава Україні

5

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


4
声明 char *argv[] 是一个指向 char 的指针数组(大小未确定),换句话说是一个字符串数组。
所有数组都会衰变为指针,因此您可以使用数组作为指针(就像您可以使用指针作为数组)。所以 *++argv 首先增加“指针”以指向数组 argv 中的下一个条目(在循环中第一次将是第一个命令行参数),然后对该指针进行解引用。

2

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


0

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

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


-1
这里做的是指针算术运算。
实际上并没有改变指针本身。
暂时使用指针的地址进行递增,然后用于输出。
因为 ++ 运算符放在 argv 前面,所以首先取得地址,然后递增,再通过解引用获取该地址后面的 char*。
但实际上并没有改变地址本身,只是改变了 printf 读取的偏移量。
明白吗?

5
指针被使用预递增操作符大量改变。但是,你知道,这是C语言,不是一些旨在保护我们免受自己伤害的婆婆妈妈的计算机科学语言。想要修改你的过程参数?去试试吧!我们是C!我们很强壮!我们是(&#$(&(*#内存位置0处的地址异常。 - Bob Jarvis - Слава Україні
很抱歉这么晚才回复。WTF。我一直以为这个前缀自增操作符只是用来获取“前一个位置”,并不会真正改变指针本身,也就是说,只是在运行时访问。好吧,我想我需要再读一遍(必须承认)。 - icbytes

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