我有以下代码:
#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.
我无法理解为什么会这样,因为我做的完全一样
两种情况都是如此。
感谢。
答案 0 :(得分:7)
运行时(通常是crt0&amp; kernel)保证(根据C99或POSIX标准)(main
的参数argc
&amp; argv
):
argc
是肯定的
argv
是指向NULL
指针数组的有效非argc+1
指针
argv[argc]
是NULL
指针
对于0和i
之间的每个argc-1
,argv[i]
是指向零终止字符串的(有效非NULL
)指针
因此,使用argv[j]
(或j>argc
)访问j<0
为undefined behavior(UB) - 因此,只有深入了解实施细节才能解释所发生的情况...
有效argv[i]
不是pointer aliases,所以i
&amp; 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的程序可能有时候出现在&#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
中有多少条。