为什么将数组作为实际参数发送给需要指向数组的指针的函数需要取消引用 2 次才能访问该数组?

Adw*_*yay 1 c arrays pointers dereference implicit-conversion

#include<stdio.h>
int fun(int (*x)[3]) {
    return **x*2; // Why we need to dereference two times here?
}
int main(void) {
    int a[3] = {1, 2, 3};
    printf("%d", fun(a)); // 2
}
Run Code Online (Sandbox Code Playgroud)

所以我所知道的是数组名称仅作为数组的地址,并且在函数中 x 也期待数组的地址,所以为什么我们需要取消引用 x 两次而不是一次?

Vla*_*cow 5

对于这次通话中的初学者

printf("%d", fun(a));
Run Code Online (Sandbox Code Playgroud)

表达式a(数组指示符)被隐式转换为指向具有 type 的元素类型的指针int *

同时函数参数的类型为int ( * )[3]

没有从类型int *到类型的隐式转换int ( * )[3]。所以编译器会报错。

函数调用必须看起来像

printf("%d", fun( &a ));
Run Code Online (Sandbox Code Playgroud)

在取消引用指针的函数中,x您将获得int[3]原始数组左值类型的对象。再次在表达式中使用(极少数例外),数组指示符被转换为指向int *其第一个元素的类型的指针。

因此,要访问数组的第一个元素,您需要再次取消引用表达式

**x*2
Run Code Online (Sandbox Code Playgroud)

您有以下表达式转换链

&a -> int ( *x )[3]

*x -> int[3]

int[3] -> int *

*( int * ) -> int
Run Code Online (Sandbox Code Playgroud)