指向一维数组或二维数组的指针变量?

Pointer variable pointing to a one dimensional array or two dimensional array?

我有以下一维数组代码:

#include <stdio.h>
int main()
{
    static int b[4] = {11, 12, 13, 14};
    int (*p)[4];

    p = b;
    printf("%d \n", *(p + 1));

    return 0;
}

尽管我将“b(数组名称)”视为指向一维数组的指针,但我还是遇到了编译错误

'=': cannot convert from 'int [4]' to 'int (*)[4]'

但是,如果我将 b 数组更改为二维数组“a(数组名称)”,一切正常。这是否意味着,在“int (*p)[4];”的用法中,“*p”必须表示a[],如下所示:

static int a[3][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} };
int (*p)[4];
p = a;

因此,“int (*p)[4]”仅提供二维数组行数的灵活性。

对这个问题有什么见解吗?

数组自然地 衰减 指向其第一个元素的指针,具体取决于上下文。也就是说,当发生这种衰减时,普通的 b&b[0] 相同,后者的类型为 int *。由于 pb(或 &b[0])的类型不同,您会得到一个错误。

至于a在这里也是一样的,它衰减到指向它的第一个元素的指针,即a&a[0]相同。 但是因为a[0]是一个包含4个元素的数组,那么&a[0]是一个指向数组的指针四个元素,或 int (*)[4]。这也是第二个例子中 p 的类型。

a pointer pointing to a one dimensional array,

不是,它直接指向第一个元素。同样:

int *p = b;

够了。

这里的数字4实际上不是任何类型的一部分;

 static int b[] = {11, 12, 13, 14};

声明中可以省略。 (因为它是 第一个 维度,除非你将它设为 2D)


这个(来自AA)

int (*p)[4] = &b;
...
printf("%d \n", *( *p + 1 ) );

只是混淆和改写的版本:

int (*p)[] = &b;
...
printf("%d \n", (*p)[1] );

这会将 b 替换为 (*p),通常不是您想要的。

如果您有某种类型的对象T,例如

T a;

那么指向对象的指针声明将类似于

T *p = &a;

您的数组 b 的类型为 int[4]。所以指向数组的指针看起来像

int ( *p )[4] = &b;

要使用你应该写的指针输出数组的第二个元素

printf("%d \n", *( *p + 1 ) );

因此您的编译器发出了错误信息

cannot convert from 'int [4]' to 'int (*)[4]

因为至少不用写

int ( *p )[4] = &b;

你写了

int ( *p )[4] = b;

另一方面,在极少数例外情况下,表达式中使用的数组指示符会隐式转换为指向其第一个元素的指针。例如在这个声明中

int *p = b;

用作初始值设定项的数组 b 被转换为指向其第一个元素的指针。上面的声明等同于

int *p = &b[0];

或相同

int *p = b + 0;

使用这个指针你可以像

一样调用函数printf
printf("%d \n", *(p + 1));

如果你有一个二维数组作为

int a[3][4];

然后在表达式中使用,它被转换为指向其第一个类型为 int[4] 的元素的指针。所以你可以写

int ( *p )[4] = a;

如果要将指向整个数组的指针声明为单个对象,可以这样写

int ( *p )[3][4] = &a;