2013-08-21 30 views
5

对于下面给出的程序,为什么第一个printf会打印argv&argv的不同值?第二个printfa&a打印相同的值。将参数变量传递给程序的机制是什么?argv和正常字符串数组之间的不同输出

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

什么是存储命令行参数串

+1

printf(“%d%d”,a,&a);这里&a和a将指向相同的地址......所以您不需要同时打印它们,并使用%p代替%d来打印地址。 – sunny1304

+0

我认为这是因为argv指针已初始化,但您的指针并非如此得到相同的地址 – Saxtheowl

回答

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 

第一和第三线并不奇怪,因为用于阵列arrarr&arr具有相同的值。第二行需要解释。

正如你所看到的,当a在功能foo传递的a值没有改变,但是地址&a被改变,因为C函数总是按值传递参数,就会有争论的本地副本在函数内部。

这与argv一样,因为它只是函数main中的一个参数。


编辑:对于那些谁与我不同意,我的答案是不反对对方的回答。相反,他们完成对方。 argv是一个指针,因为它是一个作为函数参数传递的数组,它“衰减”成指针。再次,argv不是特殊的,它与其他作为函数参数传递的数组没有区别,这就是我的示例代码的全部意义。

+0

不错的示例代码!我只是认为在我看到你的答案之前,main中的'argv'有一些特殊的地方! –

+0

这不是真的答案。对于数组类型的任何变量'a','&a'和'a'作为指针将*总是*具有相同的地址。这是C中数组类型工作的结果。区别在于'argv'不是数组类型。 – newacct

+0

@newacct那么为什么'argv'是一个指针?完全是因为它是作为函数参数传递的,“衰减”成指针。 –

4

从C标准的段落6.7.6.3广告7在你的例子argva之间的区别如下:

的参数为“”类型的数组“的声明”应调整到''限定指针类型'',其中类型限定符(如果有的话)是在数组类型派生[和]中指定的那些。如果关键字static也出现在数组类型派生的[和]中,那么对于函数的每次调用,相应实际参数的值应提供对数组第一个元素的访问,其中至少与指定的元素数量一样多由尺寸表示。

因此argv是具有其自己的地址的指针,而a是一个数组并a指向的数组,这是相同的数组的地址的第一个元件的地址。

+0

+1这是真正的答案 – newacct

相关问题