如何将二维数组分配给指向数组的指针

时间:2021-04-30 10:15:40

标签: c pointers multidimensional-array initialization implicit-conversion

我有一个指向数组(二维数组)的指针。我喜欢将二维数组分配给一个指针

  int (*p)[2]={{1,2}};//SegFault
  int (*p)[2]=(int **){{1,2},{3,4}}; //should it be same as above? but also causing segFault/
  int (*p)[2]=(int[][]){{5,4},{5,6}};//should it be same as above two? but also causing segFault

以及如何访问这些值。访问第一个数组和第一个值是否正确 *(*(p) 。 // 它是否也有效 p[0][0] 我认为是这样,但请澄清这些访问方法纯粹是 C 的设计方式,或者如果我使用 *(*(p))p[0][0]< /p>

2 个答案:

答案 0 :(得分:2)

本声明

int (*p)[2]={{1,2}};

在语法上不正确。指针是标量对象,它们可以由一个可选地括在大括号中的表达式初始化。

在本声明中

int (*p)[2]=(int **){{1,2},{3,4}}

您正在尝试使用复合文字,但再次初始化不正确,因为 int ** 类型的对象是标量对象,并且我可以通过单个表达式进行初始化。

在这个带有复合字面量的声明中

int (*p)[2]=(int[][]){{5,4},{5,6}};

二维数组使用了不正确的类型说明符 int[][],因为数组元素的大小未知。你可以写例如

int (*p)[2]=(int[][2]){{5,4},{5,6}};

也就是说,您需要有一个将分配给指针的数组。如果您没有这样的数组,则可以使用复合文字。例如

int (*p)[2] = (int[2][2]){{1,2},{3,4}};

int (*p)[2] = (int[][2]){{1,2},{3,4}};

这是一个演示程序。

#include <stdio.h>

int main(void) 
{
    enum { N = 2 };
    
    int ( *p )[N] = ( int[N][N] ){ { 1, 2 }, { 3, 4 } };
    
    for ( size_t i = 0; i < N; i++ )
    {
        for ( size_t j = 0; j < N; j++ )
        {
            printf( "%d ", p[i][j] );
        }
        putchar( '\n' );
    }
    putchar( '\n' );
    
    int a[N][N] = { { 1, 2 }, { 3, 4 } };
    p = a;
    
    for ( size_t i = 0; i < N; i++ )
    {
        for ( size_t j = 0; j < N; j++ )
        {
            printf( "%d ", p[i][j] );
        }
        putchar( '\n' );
    }
    putchar( '\n' );
    
    int b[N] = { 1, 2 };
    p = &b;
    
    for ( size_t i = 0; i < N; i++ )
    {
        printf( "%d ", ( *p )[i] );
    }
    putchar( '\n' );
    
    return 0;
}

程序输出为

1 2 
3 4 

1 2 
3 4 

1 2 

答案 1 :(得分:2)

  • {{1,2}}; 是一个数组初始值设定项,而不是一个数组。所以代码是无效的 C - 你不能像那样初始化一个指针。这是错误的类型 int 和错误的初始化器数量。
  • (int **){{1,2},{3,4}}; 是类型为 int** 的复合文字。但同样,像这样初始化指针是无效的 C。
  • (int[][]){{5,4},{5,6}}; 是一个不完整类型的数组。无法初始化。所以这也是无效的 C。

您的所有问题都源于忽略编译器警告。对于类似 gcc 的编译器,我强烈建议将您的设置更改为 -std=c11 -pedantic-errors。那么当你编写无效的 C 时,你会得到编译器错误,而不仅仅是警告。

回答问题的正确方法是:

int (*p)[2] = (int[2][2]){ {1,2}, {3,4} };

这将创建一个与指针 p 具有相同作用域的局部作用域二维数组。这相当于:

int arr[2][2] = { {1,2}, {3,4} };
int (*p)[2] = arr;