2

如果我传递一个 int ,它将按值传递。
void something(int i)
如果我传递某种类型的数组,它将通过引用传递。
void something(int i[])
或者 void something(int *i);

像 int 这样的类型将通过值传递,数组将作为引用传递。

第一个问题是,是否还有更多类型可以通过引用传递?第二个问题是,数组的第一遍和第二
遍有什么区别?(int i[])(int *i)

编辑:我会澄清我的问题。您传递给函数的其他类型(例如数组)将在函数内部进行更改。(正如您所解释的,这并不完全是通过引用传递)。

void something(int i[])
{
i[0]=5;
}

something(i);

这不仅会在本地更改数组。

结构呢?工会?指向它们的指针也通过了吗?

4

5 回答 5

4

在 C 中,所有类型都按值传递。数组实际上并没有在函数调用中传递——当你声明一个数组参数时,编译器会默默地用一个指针替换数组,当你调用它时,你传递数组的地址第一个元素。

指针也按值传递。只是当你复制一个指针时,你仍然可以修改指向的值,所以它与传递引用非常相似(但不完全相同)。

于 2012-11-08T15:19:31.557 回答
4

一切都是按价值传递的,期间。

不同之处在于 C 如何处理数组表达式。除非它是、 或 一元运算符的操作数sizeof,或者是用于在声明中初始化另一个数组的字符串文字,否则“N-element array of ”类型的表达式将被转换(“decay”)为类型为“pointer to ”的表达式,表达式的值将是数组第一个元素的地址。_Alignof&TT

所以给出一个像这样的声明

int a[10] = {0};

每当表达式a出现在代码中除&a,sizeof a或之外的任何位置时_Alignof a,它将被转换为指针表达式,并且表达式的值将是 的地址a[0],无论表达式是否被传递给函数。

所以在像这样的函数调用中

foo(a);

将表达式a转换为指针表达式,并将指针表达式( &a[0]) 的值传递给函数。

同样,在函数参数声明中,T a[]T a[N]被解释为T *a; 无论数组表示法如何,参数都被声明为指针,而不是数组。

于 2012-11-08T15:44:47.800 回答
2

C 中的所有内容都是按值传递的。数组不是通过引用传递的,而是衰减到一个指针,就像所有其他指针一样,它是按值传递的。

按值传递指针意味着它所保存的地址被复制,并且在您使用此副本操作的函数中,该副本指向与外部指针相同的数据。但是,尝试在函数中更改指针本身的值不会影响调用者传递的指针:

void fn (int *ptr)
{
  // this is OK and the data that the pointer points to will be updated, 
  // even though the pointer itself is a copy
  *ptr = 5;

  // this will not have an effect out of the function since ptr is merely a copy
  ptr = NULL;
}

在上面的示例中,如果要更改 的值ptr,则必须将函数声明为具有int **参数,而不是int *

void fn (int **ptr)
{
  *ptr = NULL;
}
...
int *x;
// at this point, x is uninitialised
fn(&x);
// x is now NULL
于 2012-11-08T15:19:46.897 回答
0

所有类型都按值传递,但(在函数调用上下文中)数组名称的值是第一个元素的地址。

于 2012-11-08T15:19:05.397 回答
0

您可以想到的任何数据类型(甚至是您枚举的数据类型)都可以作为引用或值传递。

于 2012-11-08T15:20:07.530 回答