[英]passing arguments to the function
The output of the following ode segment is 9. I think the argument a of the function foo is passed by value. 以下ode段的输出为9。我认为函数foo的参数a通过值传递。 Is my assumption correct.
我的假设正确吗? If so, how the output become 9?
如果是这样,输出如何变为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;
}
The []
syntax for a function parameter's type is just syntactic sugar. 函数参数类型的
[]
语法只是语法糖。 A pointer is passed in this case, just like with any other use of an array in a function call context. 在这种情况下,就像在函数调用上下文中对数组的任何其他使用一样,传递指针。 That means your
foo()
function's signature is equivalent to: 这意味着您的
foo()
函数的签名等效于:
void foo(int (*b)[3])
That is, it accepts a pointer to an array of three integers. 也就是说,它接受一个指向三个整数的数组的指针。 With that in mind, let's look at what your implementation does.
考虑到这一点,让我们看一下您的实现是做什么的。 First,
++b
advances the pointer to point to the next array of 3 integers in memory. 首先,
++b
使指针前进,以指向内存中下一个 3个整数的数组。 That is, it advances b
by 3 * sizeof(int)
. 也就是说,它使
b
前进3 * sizeof(int)
。 In the case of your program, that means it's pointing at the "middle row" of a
- the { 4, 5, 6 }
row. 在你的程序的情况下,这意味着它的指向的“中间行”
a
-的{ 4, 5, 6 }
行。
Next, you access element [2][1]
of the new b
. 接下来,访问新
b
元素[2][1]
。 That is, row two, element one of this new offset logical array. 也就是说,第二行是此新偏移逻辑数组的元素之一。 That causes your program to write to an address past the end of
a
, which is undefined behaviour. 这会导致您的程序将写入的地址超出
a
末尾,这是未定义的行为。 At this stage, all bets are off. 在这个阶段,所有赌注都没有了。 The output of your program could be anything .
程序的输出可以是任何东西 。
You can get back to defined behaviour by changing that line to: 您可以通过将该行更改为以下内容来恢复已定义的行为:
b[1][2] = 157;
for example. 例如。 Then, print
a[2][2]
to see the change from the context of your main()
function. 然后,打印
a[2][2]
从main()
函数的上下文中查看更改。
Compiler won't copy entire array. 编译器不会复制整个数组。 if its pass by value how about passing an array of 100000 elements.
如果按值传递,则传递100000个元素的数组如何。 so its passed as "Pointer" .
因此它作为“ Pointer”传递。 The address is passed as a copy i guess.
我猜地址是作为副本传递的。 so changing the contents of address 'll change original thing too.
因此,更改地址的内容也会更改原始内容。
seems like pass by reference by pointer. 好像是通过指针传递引用。
According to: 6.2.3.1/3 & 6.7.5.3/7 根据:6.2.3.1/3&6.7.5.3/7
In the call to foo, the array expression arr isn't an operand of either sizeof or &, its type is implicitly converted from "array of int" to "pointer to int" according to . 在对foo的调用中,数组表达式arr既不是sizeof也不是&的操作数,它的类型根据隐式地从“ int数组”转换为“ pointer to int”。 Thus, foo will receive a pointer value, rather than an array value.
因此,foo将接收指针值,而不是数组值。
So when you do: 因此,当您这样做时:
void foo(int b[][3])
it is being implicitly converted to: 它被隐式转换为:
void foo((*b)[3])
The output of your program is 8 as expected.Nothing unexpected here.What you are doing in b[2][1]=9
after incrementing b
is writing 9 to the location a[3][1]
.It doesn't affect the output of a[2][1]
which remains 8 before and after you call foo()
. 程序的输出为预期的8。这没什么意外。递增
b
之后,您在b[2][1]=9
中所做的就是将9写入位置a[3][1]
这不会影响a[2][1]
的输出,在您调用foo()
之前和之后仍为8 。
http://ideone.com/eWFxht http://ideone.com/eWFxht
You certainly need to recheck your output. 您当然需要重新检查输出。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.