是的,你可以!
我不認爲你可以用數組做到這一點,但你可以與指針數組元素做。
然而,我不會這樣做,除非我有一個非常好的理由。否定索引的指針不會成爲閱讀你的代碼的人會期望的東西,所以它會很容易被誤操作。爲了清楚起見,使用基於功能的解決方案可能會更好 - 除非它需要非常快。
就這樣,讓我們來做吧!
從您的嘗試中,您可能會對數組和指針感到困惑。請記住,他們are not the same thing。
現在,C不妨礙您使用負指數,which can make sense when you're using a pointer。所以,你可以這樣做:
int a[5];
int *b = a + 2; // or &a[2]
b[-2] // is a[0]
b[-1] // is a[1]
b[0] // ia a[2], etc
所以,我認爲下面的代碼將適合你。
#define GRIDSIZE 101
.....
int map_memory[GRIDSIZE][GRIDSIZE];
int *map_rows[GRIDSIZE];
int **map;
int i;
int gridMidPoint = GRIDSIZE/2;
for(i = 0; i < GRIDSIZE; i++) {
map_rows[i] = &(map_memory[i][0]) + gridMidPoint;
}
map = map_rows + gridMidPoint;
然後你可以使用它完全按照你所期望的 - 與101的網格大小:
for(i = -50; i <= 50; i++) {
for(j = -50; j <= 50; j++) {
map[i][j] = i+j;
}
}
,或者更一般地說:
for(i = -1 * gridMidPoint; i <= gridMidPoint; i++) {
for(j = -1 * gridMidPoint; j <= gridMidPoint; j++) {
map[i][j] = i+j;
}
}
由於創建兩個數組在堆棧上,沒有必要釋放任何東西。
這裏發生了什麼?讓我分解它。首先,我們創建支持數組:
int map_memory[GRIDSIZE][GRIDSIZE];
接下來,我們希望,我們要使用是我們行的指針數組:
int *map_rows[GRIDSIZE];
我們需要這些是指針,因爲他們將指向我們剛剛創建的二維數組中的數組中間。
int gridMidPoint = GRIDSIZE/2;
這裏我們計算中點。我假設你想在零的每一邊有相同數量的數組元素 - 所以你不需要你的例子中的+1。
for(i = 0; i < GRIDSIZE; i++) {
map_rows[i] = &(map_memory[i][0]) + gridMidPoint;
}
該代碼遍歷我們行數組中的每個元素,並將該行設置爲指向二維數組中的相關行的中間。你也可以寫:
map_rows[i] = &map_memory[i][gridMidPoint];
但是我個人認爲,隨着superflous支架和另外的版本更加清晰易讀。我認爲如果你用指針做了不尋常的事情,你應該明確地說明下一個閱讀代碼的人會發生什麼。
最後,我們需要我們的map
指針指向行的中間:
map = map_rows + gridMidPoint;
,我們就大功告成了!
記住二維陣列實際上是連續的存儲器的一個塊。這意味着map[0][gridMidPoint+1]
與位置相同。這實際上與普通的二維數組沒有什麼不同,但是它在調試時需要注意。
通常的做法是使#define大寫,例如#define GRIZIZE。否則,他們看起來像變量。 – 2012-06-15 09:59:08