C 将参数传递给函数
以下ode段的输出为9。我认为函数foo的参数a是通过值传递的。我的假设正确吗。如果是这样,输出如何变为9C 将参数传递给函数,c,parameter-passing,C,Parameter Passing,以下ode段的输出为9。我认为函数foo的参数a是通过值传递的。我的假设正确吗。如果是这样,输出如何变为9 #include <stdio.h> void foo(int[][3]); int main(void) { int a[3][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} }; foo(a); printf("%d\n", a[2][1]); return 0; } void foo(int b[][3])
#include <stdio.h>
void foo(int[][3]);
int main(void)
{
int a[3][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };
foo(a);
printf("%d\n", a[2][1]);
return 0;
}
void foo(int b[][3])
{
++b;
b[1][1] = 9;
}
#包括
void foo(int[][3]);
内部主(空)
{
INTA[3][3]={{1,2,3},{4,5,6},{7,8,9};
傅(甲),;
printf(“%d\n”,a[2][1]);
返回0;
}
void foo(int b[][3])
{
++b;
b[1][1]=9;
}
编译器不会复制整个数组。如果它的pass-by值为,那么传递一个100000个元素的数组怎么样。因此它被传递为“指针”。我想这个地址是作为副本传递的。所以改变地址的内容也会改变原来的东西
似乎是通过指针传递引用。根据:6.2.3.1/3和6.7.5.3/7 在对foo的调用中,数组表达式arr不是sizeof或&的操作数,它的类型根据类型从“int数组”隐式转换为“指向int的指针”。因此,foo将接收指针值,而不是数组值 所以当你这样做的时候:
void foo(int b[][3])
它被隐式转换为:
void foo((*b)[3])
你的程序的输出如预期的那样是8。这里没有什么意外。你在
b[2][1]=9
中所做的是在b
递增后将9写入位置a[3][1]
。这不会影响a[2][1]的输出
在调用foo()前后保持8
您当然需要重新检查输出。函数参数类型的[]
语法只是语法上的糖分。在这种情况下传递指针,就像在函数调用上下文中使用数组一样。这意味着您的foo()
函数的签名等效于:
void foo(int (*b)[3])
也就是说,它接受指向三个整数数组的指针。考虑到这一点,让我们看看您的实现是做什么的。首先,++b
将指针向前移动,指向内存中下一个由3个整数组成的数组。也就是说,它将b
前进3*sizeof(int)
。在您的程序中,这意味着它指向a
的“中间行”——{4,5,6}
行
接下来,访问新b
的元素[2][1]
。也就是说,第二行,这个新偏移量逻辑数组的元素1。这会导致程序写入超过a
结尾的地址,这是未定义的行为。在这个阶段,所有的赌注都没有了。程序的输出可以是任何内容
通过将该行更改为:
b[1][2] = 157;
比如说。然后,打印a[2][2]
以查看main()
函数上下文中的更改。在C中,数组从不按值传递——类型为“array of T”的参数被调整为“指向T的指针”。我运行代码,它给我8!哇,很多错误的答案。请不要用断章取义的方式编辑你的问题。不完全是这样。它会被转换为int(*b)[3]
。您的编辑可以在某种程度上改善情况。您现在缺少一个类型。此答案最接近正确,但将9写入a[3][1]
是未定义的行为。在这种情况下,OP的程序可以输出9,尽管我很难找到一个好的解释来解释为什么会发生这种情况。你怎么知道这些事情?根据ABI,堆栈上可能不会有任何东西被推送。你到底在问什么?可以在C中按值传递数组吗?不,不能在C中按值传递数组。不过,你可以使用一些技巧,比如将数组放入结构中,然后按值传递结构。