如果我传递一个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);
这不仅会在本地更改数组。
结构怎么样?工会?指向它们的指针也通过了吗?
答案 0 :(得分:4)
所有类型都在C中传递值。数组实际上并没有在函数调用中传递 - 当你声明一个数组参数时,编译器会默默地用指针替换数组,当你调用它时,你传递地址数组的第一个元素。
指针也通过值传递。只是当您复制指针时,您仍然可以修改指向的值,因此它与(通过引用传递)非常相似(但不完全相同)。
答案 1 :(得分: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
答案 2 :(得分:2)
一切都按价值,期间传递。
不同之处在于C如何处理数组表达式。除非它是sizeof
,_Alignof
或一元&
运算符的操作数,或者是用于在声明中初始化另一个数组的字符串文字,否则表达式为“N” -element数组T
“将被转换(”衰减“)到类型为”T
指针“的表达式,表达式的值将是数组的第一个元素的地址。
所以给出了像
这样的声明int a[10] = {0};
只要表达式a
出现在您的代码中&a
,sizeof a
或_Alignof a
以外的任何位置,它就会被转换为指针表达式和值表达式将是a[0]
的地址,无论表达式是否传递给函数。
所以在像
这样的函数调用中foo(a);
将表达式a
转换为指针表达式,并将指针表达式(&a[0]
)的值传递给函数。
同样,在函数参数声明中,T a[]
和T a[N]
被解释为T *a
;无论数组符号如何,该参数都被声明为指针而不是数组。
答案 3 :(得分:0)
所有类型都按值传递,但(在函数调用上下文中)数组名称的值是第一个元素的地址。
答案 4 :(得分:0)
您可以想到的任何数据类型(甚至是您枚举的数据类型)都可以作为引用或值传递。