C++数组的初始化规则
C++有几条关于初始化数组的规则,它们限制了初始化的时刻,决定了数组的元素数目与初始化器中值的数目不相同时将发生的情况。
只有在定义数组时才能使用初始化,此后就不能使用了,也不能将一个数组赋给另一个数组:
int cards[4] = {3, 6, 8, 10}; //okay
int hand [4]; //okay
hand[4] = {5, 6, 7, 9}; //not allowed
hand = cards; //not allowed
然而,可以使用下标分别给数组中的元素赋值。
初始化十足十,提供的值可以少于数组的元素数目。例如,下面的语句值初始化hotelTips的前两个元素:
float hotelTips[5] = {5.0, 2.5};
如果只对数组的一部分进行初始化,则编译器将把其他元素设置为0。因此,将数组中所有的元素都初始化为0非常简单——只要显示的将第一个元素初始化为0,然后让编译器将其他元素都初始化为0即可:
long total[500] = {0};
如果初始化为{1}而不是{0},则第一个元素被设置为1,其他元素都被设置为0。
如果初始化数组时方括号([ ])为空,C++编译器将计算元素个数。例如,对于下面的声明:
short things[] = {1, 5, 3, 8};
编译器将使things数组包含4个元素。
让编译器去做
通常,让编译器计算元素个数是种很糟的做法,因为其计数可能与您想象的不一样。例如,您可能不小心在列表中遗漏了一个值。然而,这种方法对于将字符数组初始化为一个字符串来说比较安全,很快你将明白这一点。如果主要关心的问题时程序,而不是自己是否知道数组的大小,则可以这样做:
short things[] = {1, 5, 3, 8};
int num_elements = sizeofthings / sizeof (short);
这样做是有用还是偷懒取决于具体情况。
C++11数组的初始化方法
首先,初始化数组时,可省略(=)
double earning[4] {1.2e4, 1.6e4, 1.1e4, 1.7e4}; //okay with C++11
其次,可不在大括号内包含任何东西,这将把所有元素都设置为零:
unsigned int counts[10] = {}; // all elements set to 0
float balances[100] {}; //all elements set to 0
第三,列表初始化禁止缩窄转换:
long plifs[] = {25, 92, 3.0}; //not allowed
char slifs[4] {'h', 'i', 1122011, '\0'}; // not allowed
char tlifs[4] {'h', ' i', 112, '\0'};
在上述代码中,第一条语句不能通过编译,因为浮点数转换为整型是缩窄操作,即使浮点的小数点后面为0。第二条语句也不能通过编译,因为1122011超出了char变量的取值范围(这里假设char变量的长度为8位)。第三条语句可通过编译,因为虽然112是一个int值,但它在char变量的取值内。
C++标准模板库(STL)提供了一种数组代替品——模板类vector,而C++11新增了模板类array。这些替代品比内置复合类型数组更复杂,更灵活。