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

Abh*_*bey 1 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;
}
Run Code Online (Sandbox Code Playgroud)

如果我不提供任何命令行输入,则"a"和"b"中的值
应分别为10和20,但会发生的是"a"获取值为10而"b"为0.
我无法理解为什么这种情况正在发生,因为我
在两种情况下做的都是一样的.

谢谢.

Bas*_*tch 7

运行时(通常是通过crt0内核)保证(根据C99或POSIX标准)(对于main's参数argc&argv):

  • argc 是积极的

  • argvNULL指向指针数组的有效非argc+1指针

  • argv[argc]NULL指针

  • 对于i0和argc-1包含的每个,argv[i]是一个(有效的非NULL)指向零终止字符串的指针

  • 因此获得argv[j]j>argc(或j<0)是未定义的行为(UB) -这样解释发生了什么,才可能通过深入到实现细节...

  • 有效argv[i]的不是指针别名,所以如果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;
Run Code Online (Sandbox Code Playgroud)

非常 的未定义行为(见参考文献在这里).可悲的是,UB程序有时似乎"工作"(可能不会崩溃).但在其他时候可能会发生坏事.所以你应该想象最坏的情况.


T.J*_*der 6

如果我不提供任何命令行输入,则"a"和"b"中的值应分别为10和20.

不,如果您不提供任何命令行输入,则您将访问超出argv阵列末尾的任何内容,并且可能发生任何事情(包括程序崩溃和刻录).

你的支票应该是:

int a = argc > 1 ? atoi(argv[1]) : 10;
int b = argc > 2 ? atoi(argv[2]) : 20;
Run Code Online (Sandbox Code Playgroud)

argc就是为了告诉argv您可以访问的条目数量.