兩個只是部分等效。不同之處在於:
static char daytab[2][13] = {
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
聲明瞭一個二維陣列,包括設置預留陣列空間和確保daytab
引用該內存。但是:
static char (*daytab)[13] = {
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
...只聲明一個指針。所以你試圖用一個數組初始值設定項來初始化一個指針,它不能按預期工作。沒有數組;沒有爲陣列留出任何內存。相反,您的初始化程序中的第一個數字將被分配給指針daytab
,並且編譯器會生成一條警告,通知您已經指定了許多隻是被丟棄的附加值。由於初始化程序中的第一個數字是0
,因此您只需以相當詳細的方式將daytab
設置爲NULL
即可。
所以如果你想做這種初始化,使用第一個版本 - 它會衰減到你在第二個版本中顯式聲明的相同指針類型,所以你可以用同樣的方法。如果您希望動態分配數組或獲取對已存在的另一個數組的引用,則需要使用數組指針的第二個版本。
所以,你可以這樣做:
static char arr[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } };
static char (*ptr)[3] = NULL;
ptr = arr;
...然後使用ptr
和arr
互換。或者這樣:
static char (*ptr)[3] = NULL;
ptr = malloc(2 * sizeof(*ptr));
...得到一個動態分配的二維數組(不是指針,以一維數組的數組,而是一個真正的二維數組)。當然,在這種情況下它不會被初始化。
這兩個變體的「等價」僅僅意味着二維數組,當它衰減到指向其第一個元素的指針時,會衰減到第二個變體中聲明的指針類型。一旦指針版本實際指向一個數組,兩者是等價的。但是二維數組版本爲數組設置內存,其中指針聲明不會......並且可以爲2D數組變量所不能指向的指針指定一個新值(指向另一個數組)。
在C99可以做到這一點,但(如果不是static
至少):
char (*daytab)[13] = (char [][13]){
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
堆棧空間?如果它是靜態的,那麼它會進入數據部分。 –
@BrianGordon更正了...我在輸入那個部分的時候忘記了「靜態」(我認爲......很久以前)。 – Dmitri
然後可以像這樣訪問指針'(*(daytab + leap))[i]'(關於練習) – Vladimir