此C代码的输出是什么(没有任何命令行参数运行)?
#include <stdio.h>
int main(int argc, char *argv[])
{
while (*argv != NULL)
printf("%s\n", *(argv++));
return 0;
}
在这个程序中,argv给出了char
指针数组的基址,所以
while(*argv !=NULL)
条件为true,这应该给出编译时错误,因为
*(argv++)
,不是吗?但它显示了一些输出原因?
答案 0 :(得分:4)
从C11
规范,章节§5.1.2.2.1(强调我的)中无耻地引用
-
argc
的值应为非负值。-
argv[argc]
应为空指针。- 如果
argc
的值大于零,数组成员argv[0]
通过argv[argc-1]
包含应包含指向字符串的指针 程序启动前主机环境实现定义的值。 意图是在程序启动之前为程序提供信息 来自托管环境中的其他地方。如果主机环境不具备 为字符串提供大写和小写的字母,实现 应确保以小写字母收到字符串。- 如果
argc
的值大于零,则argv[0]
指向的字符串 代表程序名称;argv[0][0]
如果是,则为空字符 程序名称不能从主机环境中获得。 如果argc的值是 大于一,argv[1]
通过argv[argc-1]
指向的字符串 代表程序参数。
上面的代码段只是打印提供的程序参数。
*argv != NULL
是检查我们是否未到达argv
数组的末尾。 printf("%s\n", *(argv++));
,让我们分解,
printf("%s\n", *argv)); //print the string pointed to by `argv`
argv++; //increment argv to point to the next string
现在,在“标题”中提出问题
[...](没有任何命令行参数运行)?
嗯,在这种情况下,argc
的值为1
,只有argv[0]
包含指向包含程序名称的字符串的指针。 argv[1]
指向NULL
(或类似的空指针)。
所以,在循环中
*argv
== argv[0]
不是NULL),它打印程序名称argv
作为后增量的副作用递增。*argv
现在与argv[1]
相同,为NULL,条件为false,并且它命中最终的return
语句。身体中的问题
由于
*(argv++)
,这应该会产生编译时错误,不是吗?
不,不是。引用章节§6.7.6.3
参数声明为''类型''的数组应调整为''限定指针 输入'',其中类型限定符(如果有)是在[和]中指定的类型限定符 数组类型推导。 [...]
因此,argv
是一个可修改的左值,可以在这里用作后缀增量运算符的操作数。