在C中将数组作为参数传递

Passing an array as a parameter in C

为什么这段代码有效?

#include <stdio.h>

void func(int v[]){
    v[0] = 1;
}

int main(){
    int v[5] = {0};
    func(v);
    for (int i = 0; i < 5; i++)
    {
        printf("%d ", v[i]);
    }
}

我从中得到的输出是“1 0 0 0 0”,但为什么呢?我没有传递指针,为什么函数可以更改我的 main 中的数组?

是的,你正在传递一个指针。

当你写void func(int v[])声明你的函数签名时,相当于写void func(int * v).

当你写func(v)调用你的函数时,相当于func(&v[0]).

这个函数声明

void func(int v[]){
    v[0] = 1;
}

由编译器调整为声明

void func(int *v){
    v[0] = 1;
}

来自 C 标准(6.7.6.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. 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

另一方面,在这次通话中

func(v);

数组指示符 v 隐式转换为指向其第一个元素的指针。

C 标准(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. If the array object has register storage class, the behavior is undefined.

也就是函数调用等同于

func( &v[0] );

所以实际上数组的第一个元素是通过指向它的指针通过引用传递给函数的。通过下标运算符解引用指针(表达式v[0]等同于表达式*v

v[0] = 1;

引用的数组第一个元素已更改。

这是因为数组在内部被认为是一个指针。它是数组类型变量的标识符,它具有到元素类型指针的隐式转换。