5. 數組的靜態初始化

為了避免使用全局變量的缺陷,除非有一些特殊要求,否則數組變量都被聲明為局部變量。

而且,在某一程序模塊中使用的全局數組應該被聲明為靜態變量,以避免別的程序模塊使用它們。



如果一個數組被聲明為靜態全局變量,它的每個元素在程序運行之前可以被初始化。該過程是靜態初始化的一個例子。

對於數組變量,指定初始值的等號後面是對應於每個元素的一組初始值,用一對花括號把這些值括起來。

例如:

static int digits[10]={0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

聲明瞭一個全局數組digits,且每個元素初始化為它的下標值。



5.1 自動確定數組大小

當對一個數組進行初始化時,可以在聲明中不標明數組的大小。因此,可將上述數組digits的聲明寫成:

static int digits[]={0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

當編譯器遇到這種形式的聲明時,它會計算出初始值的個數,然後為數組預留同樣多的元素。

對於一些需要在程序的生命週期內改變初始值個數的數組來説,讓編譯器從初始值的個數計算出數組的大小對程序的可維護性很有用處。



5.2 確定初始化數組的大小

在C語言中,有一個標準的習語來確定已經通過靜態初始化確定大小的數組的元素個數。

對於一個數組a,可以通過以下表達式計算其中的元素的個數:

sizeof a / sizeof a[0]

該表達式用數組中整個數組的大小去除數組第一個元素的大小。

因此, 可以用下列表達式初始化一個變量nDigits保存數組中的元素個數:

static int nDigits = sizeof digits / sizeof digits[0];
printf("%d\n", nDigits);
10

其中,sizeof的介紹,參見前文 數據的內部表示法 一節。


5.3 初始化數組和標量類型

標量類型可以用在任何整型數據出現的地方。因此,可以使用任何標量類型值作為數組的下標值。這樣就增加了標量類型的功能,也簡化了它們的應用。

作為一個實例,初始化的數組可以把枚舉類型的數據轉化成與它們相對應的名字,這種操作在C語言中是不直接支持的。

例如,如果想用 FALSE 和 TRUE 兩個名字來輸出布爾類型的數據,可以聲明數組booleanNames如下,並使用printf語句:

static string booleanNames[] = {"FALSE", "TRUE"};
printf("flag=%s\n", booleanNames[FALSE]);
flag=FALSE

因為布爾類型在genlib.h中被定義為:

typedef enum {FALSE, TRUE} bool;

常量 FALSE 的內部值為0,TRUE 的內部值為1。

使用這些數值作為數組booleanNames的下標值就可以生成對應於布爾型值的字符串。

這種情況也同樣適用於連續枚舉類型。



其中,枚舉類型相關內容,參見前文 枚舉的原理 一節






參考
《C語言的科學和藝術》 —— 第11章 數組