将参数传递给函数

时间:2013-05-25 04:24:44

标签: 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])
{
   ++b;
   b[1][1] = 9;
}

4 个答案:

答案 0 :(得分:2)

函数参数类型的[]语法只是语法糖。在这种情况下传递指针,就像在函数调用上下文中使用任何其他数组一样。这意味着您的foo()函数的签名等同于:

void foo(int (*b)[3])

也就是说,它接受一个指向三个整数数组的指针。考虑到这一点,让我们来看看你的实现是做什么的。首先,++b使指针前进,指向内存中3个整数的 next 数组。也就是说,它会b提前3 * sizeof(int)。对于您的程序,这意味着它指向a - { 4, 5, 6 }行的“中间行”。

接下来,您可以访问新[2][1]的元素b。也就是说,第二行,这个新的偏移逻辑数组的元素之一。这会导致程序写入a结尾的地址,这是未定义的行为。在这个阶段,所有赌注都已关闭。您的程序输出可能是任何

您可以通过将该行更改为:

来恢复已定义的行为
b[1][2] = 157;
例如,

。然后,打印a[2][2]以查看main()功能的上下文中的更改。

答案 1 :(得分:0)

编译器不会复制整个数组。如果它传递值如何传递100000个元素的数组。所以它作为“指针”传递。我猜这个地址是作为副本传递的。所以改变地址的内容也会改变原来的东西。

似乎通过指针传递引用。

答案 2 :(得分:0)

根据:6.2.3.1/3&amp; 6.7.5.3/7

在对foo的调用中,数组表达式arr不是sizeof或&amp;的操作数,其类型根据“隐式”从“array of int”转换为“指向int的指针”。因此,foo将接收指针值,而不是数组值。

所以当你这样做时:

 void foo(int b[][3])

它被隐式转换为:

 void foo((*b)[3])

答案 3 :(得分:-1)

您的程序输出 8 符合预期。此处没有任何意外。在递增b[2][1]=9之后您在b做的是写 9 到位置a[3][1]。在您致电a[2][1]之前和之后,它不会影响foo()的输出 8

http://ideone.com/eWFxht

您当然需要重新检查输出。