所以,如果我理解正確的話,你要什麼有三個r
X r
陣列(a
,b
和c
),但希望他們三個連續存儲;基本上,後備存儲將是單個3 x r
x r
陣列。
如果大小r
在編譯時知和你在C99或支持變長數組一個C11的實施工作,你可以這樣做以下:
size_t r = ...;
double (*a)[r] = NULL;
double (*b)[r] = NULL;
double (*c)[r] = NULL;
double (*backing_store)[r][r] = malloc(3 * sizeof *backing_store);
if (!backing_store)
{
// panic and exit
}
a = backing_store[0];
b = backing_store[1];
c = backing_store[2];
你可以再使用a
,b
,並c
,好像他們是正規r
X r
陣列double
:
a[i][j] = ...;
printf("%f\n", b[x][y]);
等
當你完成,你只需要釋放backing_store
:
free(backing_store);
爲什麼這項工作?
表達backing_store
具有類型「指針r
r
的double
- 元素陣列的陣列 - 元素,由於表達backing_store[i]
相當於*(backing_store + i)
,下標操作者隱含地取消引用指針,所以表達式的類型是」 r
r
的double
- 元素陣列」,每個的backing_store[0]
,backing_store[1]
,並backing_store[2]
的 - 元素陣列是r
X r
陣列的double
。
請記住,在大多數情況下s,類型「N
-element array of T
」的表達式被隱含地轉換(「decays」)爲類型「指向T
」的表達式,並且其值是數組中的第一個元素的地址。
因此,表述backing_store[0]
從類型「r
r
的double
- 元素陣列的陣列 - 元素」轉換爲「指針r
的double
- 元素陣列」,這恰好是的a
的類型,和值是第一個子數組的地址(恰好與backing_store
相同)。同樣,應用下標運算符會隱式地解除對指針的引用,因此a
之後給出i
th數組的第j
個元素。
如果r
爲在編譯時已知(即,它是一個常量表達式),那麼該過程是一樣的,只是你不必聲明變量r
:
#define R ...
double (*a)[R] = NULL;
double (*b)[R] = NULL;
double (*c)[R] = NULL;
double (*backing_store)[R][R] = malloc(3 * sizeof *backing_store);
if (!backing_store)
{
// panic and exit
}
a = backing_store[0];
b = backing_store[1];
c = backing_store[2];
如果r
是而不是在編譯時已知和您沒有可用的可變長度數組(使用C89或不支持VLA的C11編譯器),那麼它可能會變得更加混亂。在這裏,我們把backing_store
爲double
1-d陣列和計算1-d標到每個子陣:
double *a = NULL;
double *b = NULL;
double *c = NULL;
double *backing_store = malloc(3 * r * r * sizeof *backing_store);
if (!backing_store)
{
// panic
}
a = backing_store;
b = backing_store + r * r;
c = backing_store + 2 * r * r;
a[i*r+j] = ...;
printf("%f\n", b[x*r+y]);
同樣,你應該只需要釋放backing_store
當你完成:
free(backing_store);
不如使用二維下標漂亮,但它應該工作。
我不知道這個問題的答案,但是對於malloc指向矩陣的指針也不是一種好的方式,因爲指針本身就是數組? (註釋在這裏編輯:不是你的代碼只是設置我的指針到每個數組的第一個元素?我想有一個指向行的指針數組,每個指針指向它自己的數組表示它的列。) –
指針是不是數組,它們是指針。是的,指針和數組之間有密切的相關性,但是如果你只在32位機器上使用'malloc'指針來分配'sizeof(double *)',4個字節。數組的名稱可以用作指針,是的,但指向數組的第一個元素。 'p [0]'和'* p'是相同的,可以互換的。 – cdarke