是否可以在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
有什么问题?
答案 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;
}