简体   繁体   English

将参数传递给函数

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM