a及&;在C中作为函数参数传递的数组的
对于作为函数参数传递的数组,为什么a和&a的值不同?对于函数体中定义的数组,b和b没有区别。守则如下:a及&;在C中作为函数参数传递的数组的,c,arrays,C,Arrays,对于作为函数参数传递的数组,为什么a和&a的值不同?对于函数体中定义的数组,b和b没有区别。守则如下: void foo(int a[2]) { int b[2]; printf("%p %p\n", a, &a); printf("%p %p\n", b, &b); } int main() { int a[2]; foo(a); return 0; } 编辑: 因此,经过所有讨论,我了解到以下情况: 在main()中: 在f
void foo(int a[2])
{
int b[2];
printf("%p %p\n", a, &a);
printf("%p %p\n", b, &b);
}
int main()
{
int a[2];
foo(a);
return 0;
}
编辑:因此,经过所有讨论,我了解到以下情况: 在
main()
中:
在foo()
中:
基本上,当您键入
void foo(int a[2])
时,您的书写方式很有趣void foo(int*a)
我必须从标准中查找特定的引用,但是当分析函数签名时,类型为T的N个元素的数组类型的参数转换为指向T的指针。当您稍后键入foo(a)
时,a
衰减为指向复制的第一个元素的地址的指针。在foo
内部,您将main
中指向数组a
的第一个元素的指针的值与foo
中的指针a
的地址进行比较
另一方面,在相同的函数中,当数组在b
的foo
范围内时,数组的地址(&b
)和数组的第一个元素的地址(可以通过键入b
强制衰减来获得)是相同的地址
关于未来的两条简单信息:
- 函数签名中的数组被解释为指针:避免使用这种语法,使用指针语法,您会得到更少的惊喜
- 在大多数上下文中,表示数组衰减为指向第一个元素的指针的标识符
void foo( int a[2] ); // void foo( int *a );
int main() {
int x[2];
foo( x ); // foo( &x[0] ); -- inside foo, a is a copy of &x[0]
printf( "%d\n%d\n", (int)&a, (int)a ); // &a[0] which is the same address as &a
// (different type though)
}
数组不是指针。它几乎在所有上下文中都计算为指针,但其中一个显著的例外是
&
运算符
如果你调用一个以数组为参数的函数
f(a);
那里的a
计算为传递给函数的第一个元素&(a[0])
的地址
如果使用&a
则取整个阵列的地址。它与&(a[0])
具有相同的值,但类型不同<代码>&(a[0])的类型为“指向基类型的指针”,而&a
的类型为“指向基类型的数组的指针”
函数
&a
的内部是不同的。这里a
是“指向基类型的指针”,因此&a
是“指向基类型的指针”类型,您看到的地址是堆栈上指针的地址,而不是原始数组的地址。当您通过引用函数传递参数时,从技术上讲,您将元素的地址放入函数调用堆栈中。将&
与函数参数一起使用时,将获得该值的地址。我将尝试举例说明(所有地址都是任意的,仅供演示):
@Nitz是一个很好的问题。你的意思是在你的代码中不能将foo()称为foo(&a)。@算法学家:虽然我不认为这是问题的意思,但事实是你不能,因为类型不匹配。在
main
中,a
衰减为&a[0]
,类型为int*
,而&a
类型为int(*)[2]
@Algorithmist,当我在上面用foo(&a)运行代码时,不会(&a)衰减为类似的指针吗?@nitzs它成功了。但是@david是个专家,所以他肯定是对的。原型转换的另一个可能令人惊讶的效果是:在foo
,sizeof(a)!=sizeof(b)
@nitzs:我已经更新了答案,如果您需要进一步的解释,我可以尝试重写它,或者清除任何特定的疑问。当我调用foo(&a)和foo(a)时,我没有发现它们的o/p有任何细微的区别。您能看到一个示例,我们可以区分&a和a(a是数组名称时)在输出方面的任何函数调用中。@Algorithmist:void foo(int*){}int main(){int a[2];foo(&a);printf(“%d!=%d\n”、sizeof(*a)、sizeof(*a));}
。这将在调用foo
时给您一个指针类型转换无效的警告(可能是printf中的其他警告),并且运行程序的输出将包含两个不同的数字,其中第二个数字是第一个数值的两倍(可能是“4!=8”)你的意思是&a在函数内部和外部都不同。这里有点混乱,因为a
-是形式参数和实际参数的名称。为了澄清,可能最好对实际参数使用不同的名称:`intb[2];foo(b)`-这里我们将b
传递给函数。在函数体中,可以通过形式参数a
访问它。所以&a!=&b
。
void foo( int a[2] ); // void foo( int *a );
int main() {
int x[2];
foo( x ); // foo( &x[0] ); -- inside foo, a is a copy of &x[0]
printf( "%d\n%d\n", (int)&a, (int)a ); // &a[0] which is the same address as &a
// (different type though)
}
f(a);
int main()
{
int a[2] ; // a == &a == 0x001234
foo(a); // address of a (0x001234) goes to call stack,
// this value is stored in 0x00122C
// now inside foo(), &a == 0x00122C , a == 0x001234
}