C中的命令行参数,无法理解其行为

时间:2016-02-19 05:45:33

标签: c command-line

我有以下代码:

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

如果我不提供任何命令行输入,则&#34; a&#34;中的值和&#34; b&#34;
应分别为10和20,但相反的是&#34; a&#34;获得10的价值,而&#34; b&#34;得到0.
我无法理解为什么会这样,因为我做的完全一样 两种情况都是如此。

感谢。

2 个答案:

答案 0 :(得分:7)

运行时(通常是crt0&amp; kernel)保证(根据C99或POSIX标准)(main的参数argc&amp; argv):

  • argc是肯定的

  • argv是指向NULL指针数组的有效非argc+1指针

  • argv[argc]NULL指针

  • 对于0和i之间的每个argc-1argv[i]是指向零终止字符串的(有效非NULL)指针

  • 因此,使用argv[j](或j>argc)访问j<0undefined behavior(UB) - 因此,只有深入了解实施细节才能解释所发生的情况...

  • 有效argv[i]不是pointer aliases,所以i&amp; j包含0到argc-1i!= jargv[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的程序可能有时候出现在&#34;工作&#34; (那可能不会崩溃)。但在其他时候可能会发生坏事。所以你应该想象最坏的情况。

答案 1 :(得分:6)

  

如果我不提供任何命令行输入,则&#34; a&#34;中的值和&#34; b&#34;   应分别为10和20。

不,如果您没有提供任何命令行输入,那么您可以访问argv数组的末尾以及可能发生的任何事情(包括您的程序崩溃和燃烧)。

您的支票应该是:

int a = argc > 1 ? atoi(argv[1]) : 10;
int b = argc > 2 ? atoi(argv[2]) : 20;

argc的用途,告诉您可以访问的条目argv中有多少条。