用C语言创建二维数组很容易:
char (*arr)[50] = malloc(sizeof(arr) * 10 * 50); // 10x50 matrix
如何在C语言中实现三维数组?它看起来不像我可以这样做:
char (**arr)[50] = malloc(sizeof(arr) * 10 * 20 * 50); // 10x20x50 matrix?
三维数组需要知道2个维度
char (*arr)[20][50] = malloc(sizeof(char) * 10 * 20 * 50)
注意:我已经将sizeof(arr)修正为sizeof(char),因为sizeof(arr)将返回指针的大小
一种可能的方法是分配一个单维数组,例如
int width=10; length=20; height=50;
char* arr = malloc(width*length*height);
if (!arr) { perror("malloc"); exit(EXIT_FAILURE); };
有一些方法可以访问它,例如宏
#define Element(I,J,K) arr[width*length*(I)+length*(J)+(K)]
,使用Element(i,j,k)
可以使用灵活的数组成员打包所有这些,例如
struct my3dstring_st {
int width;
int length;
int height;
char arr[];
};
则有a.g.a making函数
struct my3dstring_st *
make_my3dstring (int width, int length, int height)
{
if (width<=0 || length<=0 || height<=0) return NULL;
struct my3dstring_st* s =
malloc(sizeof(struct my3dstring_st)
+ width * length * height);
if (!s) {perror("malloc"); exit(EXIT_FAILURE); };
s->width = width;
s->length = length;
s->height = height;
memset (s->arr, 0, width * length * height);
return s;
}
和内联访问函数(在头文件中):
static inline int
access_m3dstring(struct my3dstring_st*s, int i, int j, int k) {
if (!s || i<0 || j<0 || k<0
|| i>=s->width || j>=s->height || k>=s->length) return EOF;
return s->arr[i*->width*s->height + j*s->height + k];
}
我留下作为练习来写修改函数modify_m3dstring
,你可以有不安全但更快的变体,不做任何检查…
一般规则:
T *arr = malloc( sizeof *arr * n ); // for an N-element array
T (*arr)[N] = malloc( sizeof *arr * m ); // for an NxM-element array
T (*arr)[N][M] = malloc( sizeof *arr * k ); // for an NxMxK-element array
,其中大写字母表示编译时已知的值,小写字母表示运行时已知的值。高维数组的模式应该是显而易见的。
如果你正在使用C99编译器或C2011编译器,支持可变长度数组,你可以使用运行时变量的所有维度:
size_t n = some_value();
size_t m = some_other_value();
size_t k = yet_another_value();
T (*arr)[n][m] = malloc( sizeof *arr * k );
表达式*arr
的类型为T [n][m]
,因此sizeof *arr
的结果与sizeof (T) * n * m
相同;结果更容易阅读,更不容易出错。
如果你的编译器不支持vla,并且你在编译时不知道你的尺寸,你要么必须分配为1-d数组并手动计算偏移量:
T *arr = malloc( sizeof *arr * n * m * k );
...
arr[ 3*n*m + 2*m + 1] = x; // equivalient to arr[3][2][1] = x
或者,如果您可以接受您的行在内存中不是相邻的,您可以逐个分配数组:
T ***arr = malloc (sizeof *arr * n );
for (size_t i = 0; i < n; i++ )
{
arr[i] = malloc( sizeof *arr[i] * m );
for (size_t j = 0; j < m; j++ )
{
arr[i][j] = malloc( sizeof *arr[i][j] * k )
}
}
理想情况下,您应该检查每个malloc
的结果以确保它成功。你需要按照分配数组的相反顺序释放数组
char (*arr)[20][50] = malloc(sizeof(char) * 10 * 20 * 50);
sizeof(char)
保证为1。因此,可以省略
char (*arr)[20][50] = malloc(10 * 20 * 50);