以前我这样初始化一个数组,并自我感觉良好:
int a[5] = { 0 }; // 全部初始化为0
- 1
int a[5] = { 1 }; // 我想全部初始化为1
- 1
全部初始化为0的那行代码确实是没问题的,可以正常工作。问题就出在想把数组全部初始化成一个非0的数,即非默认值,是行不通的(查看内存发现,只有数组的第一个元素被初始化为1,其他全为0)。这倒不是因为编译器对初始化为0给了个后门,而是因为一条基本语法规则:
数组初始化列表中的元素个数小于指定的数组长度时,不足的元素补以默认值。
对于基本类型int来说,当然就是补int()即0了。再看一下非基本类型的数组:
string a[5] = { "foo" };
- 1
string a[5] = { "foo", "", "", "", "" };
- 1
还有一个区别:
-
int a[
5];
-
string a[
5];
- 1
注意,在C++11中中间的赋值号可以省略,即 int a[5]{1}; 并且,如果初始化列表为空,如 int a[5]{},那将初始化所有元素为默认值,即与 int a[5]{0}; 等价
动态数组的初始化
说完了栈中的数组的初始化,我发现new一个数组和其又有一些不同:
-
int* a =
new
int[
5];
-
string* a =
new
string[
5];
-
int* a =
new
int[
5] {
0 };
-
string* a =
new
string[
5] {
"foo" };
- 1
int* a = new int[5]();
- 1
看到这对圆括号,我想它该不会是元素的构造函数的参数列表吧,那么我可能会想将数组全部初始化为1:new int[5](1); 看起来很合理,但其实不行。事实上这对圆括号不是数组元素的构造参数,
可能是整个数组的,它有三个重载版本:



看起来像是常引用、右值引用、和默认版本。所以假如已经有一个相同大小的数组b,试着用b来初始化a:
int* a = new int[5](b);
- 1
错过了初始化时机(memset的误区)
如果想在数组创建结束后再对其进行初始化,可以使用C函数memset(),但是memset的使用有个大问题,就是它只对char类型的数组管用:
-
char a[
10];
-
memset(a,
1,
10);
// 将每个元素设置为1
- 1
-
int a[
10];
-
memset(a,
1,
sizeof(a));
- 1
如果实在想再初始化,那么老老实实循环赋值吧。
转载自:https://blog.youkuaiyun.com/u014417133/article/details/77185009#commentBox