简体   繁体   English

可以在C中传递值吗?

[英]Pass by value possible in C?

Hello I was reading this question, I got confused with how if we can pass arrays by value or not. 您好我正在阅读这个问题,我对如何按值传递数组感到困惑。 Here is a piece of code which I think should pass array by value. 这是一段代码,我认为应该按值传递数组。

#include <cstdio>
void foo (int arr[]);
int main()
{
    int arr[10];
    foo(arr[10]);
    return 0;
}
void foo (int arr[])
{
.......
}

Please tell me why wouldn't it pass by value? 请告诉我为什么不通过价值?

Thanks 谢谢

Arrays automatically decay into pointers in certain contexts in C. Function calls are one of those places. 数组在C中的某些上下文中自动衰减为指针。函数调用是其中一个地方。 That said, you are passing the pointer by value - C has no other way to pass parameters than "by value". 也就是说,你是按值传递指针 - C没有其他方式传递参数而不是“按值”。

Because this: 因为这:

void foo(int arr[])

is really just syntax sugar for this: 这真的只是语法糖:

void foo(int *arr)

So when you call the function, your array decays into a pointer to the first element. 因此,当您调用该函数时,您的数组会衰减为指向第一个元素的指针。

In short: you cannot pass an array as a function parameter and have it received as an array type by the called function. 简而言之:您不能将数组作为函数参数传递,并将其作为数组类型通过被调用函数接收。 An array expression in that context will be converted to a pointer type before it is passed to the function. 该上下文中的数组表达式在传递给函数之前将转换为指针类型。

From the C language standard : 从C语言标准

6.3.2.1 Lvalues, arrays, and function designators 6.3.2.1左值,数组和函数指示符
... ...
3 Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type ''array of type '' is converted to an expression with type ''pointer to type '' that points to the initial element of the array object and is not an lvalue. 3除非它是sizeof运算符或一元&运算符的操作数,或者是用于初始化数组的字符串文字,否则将类型为''array of type ''的表达式转换为类型为''指针的表达式键入 ''指向数组对象的初始元素,而不是左值。 If the array object has register storage class, the behavior is undefined. 如果数组对象具有寄存器存储类,则行为未定义。

What this means is that when you write something like 这意味着当你写下类似的东西时

int arr[10];
foo(arr);

the expression arr in the call to foo is immediately converted to a pointer type; 调用foo的表达式arr会立即转换为指针类型; it is said to "decay" to type int * . 它被称为“衰变”以输入int * So all foo will ever receive is a pointer value. 所以所有foo都会收到一个指针值。

More standard language: 更标准的语言:

6.7.5.3 Function declarators (including prototypes) 6.7.5.3函数声明符(包括原型)
... ...
7 A declaration of a parameter as ''array of type '' shall be adjusted to ''qualified pointer to type '', where the type qualifiers (if any) are those specified within the [ and ] of the array type derivation. 7参数声明为'' 类型数组''应调整为''限定指向类型 '',其中类型限定符(如果有)是在数组类型派生的[]中指定的那些。 If the keyword static also appears within the [ and ] of the array type derivation, then for each call to the function, the value of the corresponding actual argument shall provide access to the first element of an array with at least as many elements as specified by the size expression. 如果关键字static也出现在数组类型派生的[]中,则对于每次对函数的调用,相应实际参数的值应提供对数组的第一个元素的访问,其中至少有指定的元素数量。按大小表达式。

What this means is that if your prototype for the function foo is either 这意味着如果你的函数foo原型是

void foo(int arr[])

or 要么

void foo(int arr[10])

it will be interpreted as 它将被解释

void foo(int *arr)

Again, the definition of the language is such that you cannot pass an array expression as a function parameter and have it be received as an array type by the called function. 同样,语言的定义是这样的,你不能将数组表达式作为函数参数传递,并让被调用函数作为数组类型接收它。

There are ways around this; 有办法解决这个问题; you can wrap the array in a struct and pass the struct by value, like so: 您可以将数组包装在struct并按值传递struct ,如下所示:

struct T { int arr[10]; } var;
foo(var);
...
void foo (struct T arg) { ... }

As hacks go, this doesn't really buy you much. 随着黑客的进攻,这并没有真正为你买单。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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