对于下面给出的计划,为什么第一个printf
会为argv
和&argv
打印不同的值?第二个printf
打印a
和&a
的相同值。传递给程序的参数变量的机制是什么?
#include<stdio.h>
int main(int argc, char * argv[]){
char * a[10];
printf("%d %d\n\n",argv,&argv);
printf("%d %d",a,&a);
return 0;
}
将命令行参数存储到字符串数组的机制是什么
答案 0 :(得分:5)
问题不在于argv
是特殊的,而是关于函数参数传递。试试这个程序:
#include<stdio.h>
void foo(int a[])
{
int b[10];
printf("foo :%p %p\n",a,&a);
printf("foo :%p %p\n",b,&b);
}
int main(int argc, char* argv[])
{
int a[10];
printf("main:%p %p\n", a, &a);
foo(a);
return 0;
}
我的机器中的输出:
main:0x7fffb4ded680 0x7fffb4ded680
foo :0x7fffb4ded680 0x7fffb4ded628
foo :0x7fffb4ded630 0x7fffb4ded630
第一行和第三行并不奇怪,因为对于数组arr
,arr
和&arr
具有相同的值。需要解释第二行。
如您所见,在函数a
中传递foo
时,a
的值不会更改,但地址&a
会因C函数而更改总是按值传递参数,函数内部会有一个局部的参数副本。
与argv
相同,因为它只是函数main
中的一个参数。
编辑:对于那些不同意我的人,我的回答并不反对另一个答案。相反,他们互相完成。 argv
是一个指针,因为它是一个作为函数参数传递的数组,并且它“衰减”成一个指针。同样,argv
并不特殊,它与作为函数参数传递的其他数组没有区别,这是我的示例代码的全部要点。
答案 1 :(得分:4)
示例中argv
和a
之间的差异来自C标准的第6.7.6.3段和第7段:
将参数声明为''类型数组''应调整为''类型''的限定指针,其中类型限定符(如果有)是[和]数组类型派生。如果关键字static也出现在数组类型派生的[和]中,则对于每次对函数的调用,相应实际参数的值应提供对数组的第一个元素的访问,其中至少有指定的元素数量。按大小表达式。
结果argv
是一个有自己地址的指针,而a
是一个数组而a
指向数组第一个元素的地址,即与数组的地址相同。