C语言非常道
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

5.1.2 数组变量的初始化

我们已经讲过,可以在变量的声明中用符号“=”连接一个初始化器,当变量创建时,就用初始化器的值来初始化变量,例如:

              int x = 6, * p = & x;

如果一个变量以其类型而言是由子变量组成,则它的初始化器必须用一对花括号“{”和“}”围起来。在数学上,我们也是用花括号来形成一个集合的。

既然是子变量,那么,每个子变量也都需要一个初始化器。所以,初始化器是迭代组成的,一个数组变量的初始化器由子变量的初始化器组成,子变量的初始化器用逗号“,”分隔开,用来为对应的元素(子变量)提供初始值,例如:

              /*************c0501.c*************/
              int main(void)
              {
                  int studs [5] = {1, 2, 3, 4, 5};
              }

在这里,{1, 2, 3, 4, 5}是数组变量studs的初始化器,表达式1、2、3、4、5分别是其每个元素(子变量)的初始化器。表达式1为数组studs的第一个元素提供初始值;表达式2为数组studs的第二个元素提供初始值,后面以此类推。

之所以这里的1、2、3、4、5都没有用花括号围起来,是因为数组studs的每个元素都不再包含子变量。

现在,我们将上面的程序保存为源文件c0501.c,然后用-g选项翻译为可执行程序。在gdb中,将断点设置在右花括号“}”所在的那一行,运行程序,用调试命令“p studs”观察数组的内容。如下面的交互过程所示,gdb以集合的形式显示数组的每个元素:

             (gdb)p studs
              $1 = {1, 2, 3, 4, 5}
             (gdb)

数组元素的初始化器还可以包含一个指示器,用于指定初始化哪个元素。指示器是一个用方括号围起来的元素下标,例如:

              /**********c0502.c********/
              int main(void)
              {
                  int a [50] = {[22] = 8};
              }

这里,[22] = 8是子变量的初始化器,它由指示器“[22]”、符号“=”,以及一个用于提供实际数值的表达式8组成,该初始化器用于初始化那个下标为22的元素,因为这是指示器指定的元素。

现在,我们将上面的程序保存为源文件c0502.c,然后用-g选项翻译为可执行程序。在gdb中,将断点设置在右花括号“}”所在的那一行,运行程序,用调试命令“p a”观察数组的内容。如下面的交互过程所示,gdb以集合的形式显示数组的每个元素:

             (gdb)p a
              $1 = {0 <repeats 22 times>, 8, 0 <repeats 27 times>}
             (gdb)

和上一个例子不同,这一次gdb的p命令似乎并未显示所有数组元素的值。实际上它已经全部予以显示,只不过比较简略。首先,“0<repeats 22 times>”的意思是有22个重复出现的0(包括已经显示的这个0)。换句话说,数组的前22个元素都是0。然后,中间的8表示第23个元素的值是8;最后,“0<repeats 27 times>”的意思是有27个重复出现的0(包括已经显示的这个0)。换句话说,从第24个元素开始,一直到数组的最后一个元素,它们的值都是0。

如果数组的初始化器里没有指示器,那么,初始化的顺序是按元素的下标顺序进行的,先初始化下标为0的元素,然后是下标为1的元素,其他以此类推;如果初始化器的数量少于元素的数量,则剩余的元素被初始化为0;如果数组的初始化器里有指示器,则后续的初始化将延续指示器的下标进行,直至遇到另一个指示器。

在下面的示例中,数组a中下标为0的元素被初始化为1,下标为1的元素被初始化为2,其余的元素被初始化为0;数组b中下标为0的元素被初始化为3,下标为11的元素被初始化为33,下标为9的元素被初始化为5。紧接着,表达式1用于初始化下标为10的元素,表达式2用于初始化下标为11的元素,剩余的元素统统被初始化为0。

              /************c0503.c**********/
              int main(void)
              {
                  int a [22] = {1, 2}, b [22] = {3, [11] = 33, [9] = 5, 1, 2};
              }

注意,数组b中下标为11的元素被初始化两次,但它将保留最后一次被初始化的数值2,而不是第一次的数值33。