有人說C語言是一個很詭異的語言,所以有時候我們會見到一些比較奇怪的定義,比如:
struct A{
int a;
int data[]
};
這個看起來確實很奇怪,爲什麼數組沒有定義大小呢?
但實際上這段代碼不僅可以通過大部分編譯器,並且用途還很廣泛。我工作的時候就遇到了不少這樣的代碼,並且還是比較關鍵的代碼。
不過實際上事情並沒有那麼複雜和難以理解,不用看那些複雜的關於零長度數組是否符合C標準,以及不完整類型等等沒見過的名詞,其實道理很簡單,C也不會專門爲了這個而搞出來很複雜的規則。
讓我們來看看,什麼地方還會用到這樣類似的東東:
int f(int array[])
{
...
}
int main(void)
{
int a[10];
...
f(a);
...
}
想想看,是不是一樣的道理?
int a[]無論怎麼用,都是一個意思,就是說明a是一個數組,但是不知道它的大小。
當然在struct A的定義中,與這裏還是有些不同的,因爲int data[]並沒有佔用實際的空間,sizeof(struct A) = 2(或者是4,依賴於平臺)。
另外,int data[0]在有些編譯器上也可以通過,並且和int data[]具有相同的效果,所以上面的結構體聲明可能看起來象下面這樣:
struct A{
int a1;
int data[0];
};
這種寫法不推薦使用,因爲不符合C的標準,而且看起來更怪更難以理解。
引用別人的一個例子,就可以更深入的理解了:
#include "stdio.h"
#include "stdlib.h"
struct A{
short a1;
short next[0];
} * pA = NULL;
struct B{
short a1;
short next[1];
};
main()
{
short abc[10];
int i;
printf("sizeof(struct A)=%d, sizeof(short)=%d, sizeof(struct B)=%d/r/n", sizeof(struct A), sizeof(short), sizeof(struct B));
for (i=0; i<10; i++) abc[i] = i;
pA = (struct A * ) abc;
for (i=0; i<10; i++) {
printf("i: %d, i.next:%d/r/n", pA->a1, pA->next[0]);
pA++;
/*
注意與的不同,下面的語句要考慮到入棧的順序,i和i.next的輸出是相同的
printf("i: %d, i.next:%d/r/n", pA->a1, pA++->next[0]);
*/
};
getch();
}
注:例子來源於http://www.etcell.com/soft/topicView.aspx?Id=38200,我是用baidu的cache看到的,看不到作者的名字,就不寫了,大家看到了幫忙告訴我,我寫上。另外,代碼修改了一句,以便突出重點。