c - 指向2d数组的静态2d数组

时间:2014-09-25 07:59:10

标签: c arrays pointers

是否可以在C中创建静态地创建指向2d数组的指针数组,例如:

#define m 4
#define n 4
#define p 2
#define q 2

char arr1[m][n] = {{0}};
char arr2[m][n] = {{0}};
char (*parr[m][n])[p][q] = {{&arr1, 0, &arr2, 0}};

int main() {
    return 0;
}

2d指针数组parr是稀疏的,有些值为0(NULL),这就是为什么我不想在第一时间使用4d数组。

编译,但我收到以下警告:

  

警告:从不兼容的指针类型初始化

使用以下命令:

  

gcc -Wall -Wextra -pedantic -std = c99 test.c

有什么问题?

4 个答案:

答案 0 :(得分:2)

问题是当你声明指针,数组和数组指针时,[]优先于*,除非你添加括号。这就是为什么你将数组指针声明为(*parr)[]而不是*parr[],因为后者提供了一个指针数组。

同样,在声明指向2D数组的指针时,您可以键入(*parr)[m][n]。因此,将二维数组指针数组声明为((*parr)[m][n])[p][q])似乎是合乎逻辑的。但是这里的外括号实际上什么也没做,表达式等同于(*parr)[m][n][p][q]。这是一个指向4D阵列的数组指针!这就是你得到编译器警告的原因。

现在你真正想要的是获得一个指向2D数组的数组指针数组,就像char (*parr[p][q])[m][n]一样。这看起来很疯狂,没有人会理解这样的声明。

编写这样的代码的唯一理智方法是通过typedef:

typedef char arr_t[m][n];

arr_t arr1 = {{0}};  
arr_t arr2 = {{0}};  
arr_t* parr[p][q] =
{
  {&arr1, 0},
  {&arr2, 0}
};

答案 1 :(得分:1)

我认为您打算做的事情如下:

char arr1[m][n] = {{0}};
char arr2[m][n] = {{0}};

typedef char (*some_type)[n];  // type of arr1 and arr2
some_type parr[p][q] = {{arr1, NULL}, {arr2, NULL}};  //array containing arr1 and arr2

然后您可以通过

访问parr
printf("%c\n", parr[0][0][0][0]);

将打印arr1[0][0]

答案 2 :(得分:1)

parr 的声明中,我认为您打算使用 p q 作为其维度:

$ cat test.c
#include <stdio.h>

#define m 4
#define n 4
#define p 2
#define q 2

char arr1[m][n] = {{0}};
char arr2[m][n] = {{0}};

char (*parr[p][q])[m][n] = {{&arr1, NULL}, {&arr2, NULL}};

int main(void)
{
    printf("%d\n", (*parr[0][0])[0][0]);
    return 0;
}

使用GCC 4.8.2完全编译:

$ gcc --version
gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ gcc -ansi -fsanitize=address -g -pedantic -Wall -Wextra -Wfatal-errors -Wno-unused-parameter -o test test.c
$

答案 3 :(得分:0)

这将是我的解决方案 - 我更喜欢使用静态1D数组而不是静态2D数组因为指针算法(我喜欢简单化):

PS。我建议使用m!= n和p!= q进行测试,这样你就可以捕获可能的索引错误!

#include <stdio.h>

#define m 4
#define n 4
#define p 2
#define q 2


char arr1[m*n] = {0};
char arr2[m*n] = {0};
typedef char array_2d[m][n];

char* parr[p][q] = { {(char*)arr1, NULL}, { (char*)arr2, NULL} };


int main() 
{
    for (int i = 0; i < m; i ++ )
    for (int j = 0; j < n; j ++ )
    {
       arr1[i*n + j] = i + j;
       arr2[i*n + j] = i - j;
    }

     for (int i = 0; i < m; i ++ )
     {
         for (int j = 0; j < n; j ++ )
         {
            char* arr1_ptr = parr[0][0];
            char* arr2_ptr = parr[1][0];
            printf("%d", (int)(arr1_ptr[i*n + j] - arr2_ptr[i*n + j] ));
         }
         printf("\n");
     }

    return 0;
}