用C創建二維數組很簡單:如何在C中分配3維數組?
char (*arr)[50] = malloc(sizeof(arr) * 10 * 50); // 10x50 matrix
你怎麼做用C三維數組?它看起來並不像我可以這樣做:
char (**arr)[50] = malloc(sizeof(arr) * 10 * 20 * 50); // 10x20x50 matrix?
用C創建二維數組很簡單:如何在C中分配3維數組?
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(炭),因爲sizeof(arr)將返回指針的大小。
'sizeof(char)'總是多餘的...... – Deduplicator
是的,我同意。我傾向於這樣做,以便於識別分配的類型。或者更好的辦法是說malloc(sizeof(char [10] [20] [30]))。 – user1969104
在這種情況下,你做錯了。 'sizeof *** arr'是有道理的,但最好的情況* *文檔*變得陳舊和*不*錯誤。 – Deduplicator
char (*arr)[20][50] = malloc(sizeof(char) * 10 * 20 * 50);
sizeof(char)
保證是1.因此,它可以省略。
char (*arr)[20][50] = malloc(10 * 20 * 50);
一種可能的方式可能是分配單維數組,
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[];
};
然後有ag一個決策函數
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
,你可能有不安全的,但更快的變體不做任何檢查...
謝謝,這非常酷!修改函數可以像'Element [i,j,k] = x;':)一樣簡單 – bodacydo
如果您想要修改某些'struct my3dstring_st *'指針作爲參數傳遞,則不會。我的宏'元素'只適用於'arr'是* global *變量(或形式參數但很醜)。 –
static-inline int access_m3dstring(struct my3dstring_st * s,int i,int j,int k,char val){if {|| || || <0 || j <0 || k <0 || i > = s-> width || j> = s-> height || k> = s-> length)return EOF; s-> arr [i * - > width * s-> height + j * s-> height + k] = val; }' – bodacydo
一般規則:
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
相同的結果;結果更容易閱讀並且不易出錯。
如果你的編譯器不支持沃拉斯,你不知道在編譯時你的尺寸,你要麼必須分配爲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
的結果,以確保它成功了。你必須按照你分配的順序釋放數組:
'sizeof(char)* 10 * 50'將是一個10x50的字符矩陣,不是? –
@RickyMutschlechner會的。 :)但它是一個2-dim矩陣。但我不知道如何做3-dim ... – bodacydo
@RudyVelthuis這與編寫sizeof(char)相同。 (編輯:我認爲) – bodacydo