C中的命令行参数,无法理解其行为
Posted
技术标签:
【中文标题】C中的命令行参数,无法理解其行为【英文标题】:Command line arguments in C, cant understand its behaviour 【发布时间】:2016-02-19 05:45:32 【问题描述】:我有以下代码:
#include <stdio.h>
int main(int argc, char* argv[])
int a = argv[1]?atoi(argv[1]):10;
int b = argv[2]?atoi(argv[2]):20;
printf("a = %d, b = %d\n", a, b);
return 0;
如果我不提供任何命令行输入,“a”和“b”中的值 应该分别为 10 和 20,但实际上“a”的值为 10,而“b”的值为 0。 我不明白为什么会这样,因为我做的完全一样 在这两种情况下。
谢谢。
【问题讨论】:
因为您正在调用未定义的行为。如果未提供命令行参数,则代码不得访问那些arg
条目。在这种情况下,不能保证它们都为 NULL。只有 argv[argc]
被 C 标准定义为 NULL。
在第三和第四行,尝试将argv[1]
和argv[2]
更改为(argc>1)
和(argc>2)
我尝试检查 argv[1] 和 argv[2] 是否为空,结果 argv[2] 不为空,即使我没有在命令行上提供任何输入。谢谢。
【参考方案1】:
运行时(通常通过crt0 和kernel)保证(根据C99 或POSIX 标准)(对于main
的参数argc
和argv
):
argc
为正
argv
是一个有效的非 NULL
指针,指向 argc+1
指针数组
argv[argc]
是NULL
指针
对于包含在 0 和 argc-1
之间的每个 i
,argv[i]
是一个(有效的非 NULL
)指针,指向一个以零结尾的字符串
因此使用j>argc
(或j<0
)访问argv[j]
是undefined behavior (UB) - 所以只有通过深入了解实现细节才能解释发生的事情......
有效的argv[i]
不是pointer aliases,所以如果i
和j
都在0 和argc-1
之间,并且i
!= j
, argv[i]
! = argv[j]
因此,您的代码在argc==1
时是错误的,因为访问argv[2]
是被禁止的(UB)。
你应该编码:
int main(int argc, char* argv[])
int a = (argc>1)?atoi(argv[1]):10;
int b = (argc>2)?atoi(argv[2]):20;
非常 scared 的未定义行为(另请参阅参考资料 here)。遗憾的是,带有 UB 的程序可能有时似乎“工作”(可能不会崩溃)。但在其他时候,坏事可能会发生。所以你应该想象最坏的情况。
【讨论】:
【参考方案2】:如果我不提供任何命令行输入,“a”和“b”中的值 应该分别是 10 和 20。
不,如果您不提供任何命令行输入,您访问的将超出argv
数组的末尾,并且任何事情都可能发生(包括您的程序崩溃和烧毁)。
你的支票应该是:
int a = argc > 1 ? atoi(argv[1]) : 10;
int b = argc > 2 ? atoi(argv[2]) : 20;
这就是argc
的用途,告诉您argv
中有多少条目可供您访问。
【讨论】:
以上是关于C中的命令行参数,无法理解其行为的主要内容,如果未能解决你的问题,请参考以下文章