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章 数组