我有以下代码:
#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.
我无法理解为什么这种情况正在发生,因为我
在两种情况下做的都是一样的.
谢谢.
运行时(通常是通过crt0和内核)保证(根据C99或POSIX标准)(对于main's参数argc&argv):
argc 是积极的
argv是NULL指向指针数组的有效非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程序有时似乎"工作"(可能不会崩溃).但在其他时候可能会发生坏事.所以你应该想象最坏的情况.
如果我不提供任何命令行输入,则"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您可以访问的条目数量.