在C中创建二维数组很简单:
char (*arr)[50] = malloc(sizeof(arr) * 10 * 50); // 10x50 matrix
你如何用C做三维数组?我看起来不像以下那样:
char (**arr)[50] = malloc(sizeof(arr) * 10 * 20 * 50); // 10x20x50 matrix?
答案 0 :(得分:3)
三维数组需要知道2个维度
char (*arr)[20][50] = malloc(sizeof(char) * 10 * 20 * 50)
注意:我已将sizeof(arr)更正为sizeof(char),因为sizeof(arr)将返回指针的大小。
答案 1 :(得分:1)
可能的方法是分配一维数组,例如
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)
您可以使用flexible array member之类的
打包所有这些内容 struct my3dstring_st {
int width;
int length;
int height;
char arr[];
};
然后有一个。制作功能
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
,你可能会有不安全但速度更快的变种,不做任何检查......
答案 2 :(得分:1)
一般规则:
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并且您在编译时不知道您的维度,那么您必须分配为一维数组并手动计算偏移量:
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
的结果,以确保它成功。而且你必须按照你分配它的相反顺序释放数组:
答案 3 :(得分:0)
char (*arr)[20][50] = malloc(sizeof(char) * 10 * 20 * 50);
sizeof(char)
保证为1.因此,它可以省略。
char (*arr)[20][50] = malloc(10 * 20 * 50);