代码改变世界

c++数组初始化误区

2020-02-02 00:45  youxin  阅读(1093)  评论(0编辑  收藏  举报

看下面的一段代码:

int statusArr[100] = {1}

能达到全都初始化为1的结果么?

结果是只有第一个元素初始化了为1,其他都是0.

之前经常写

int a[100]= {0} 

这么写可以,为什么?

因为c++有个基本的语法规则,数组初始化列表中的元素个数小于指定的数组长度时,不足的元素补以默认值。当我们写0没有问题因为恰好0是int的默认值罢了。

 
string a[5] = { "foo", "", "", "", "" };

即后面4个元素调用了string的默认构造函数进行的初始化,而第一个则调用的string::string(const char*)进行的初始化。

 

还有一个区别:

int a[5];
string a[5];

如果不明确指出初始化列表,那么基本类型是不会被初始化的(除全局变量和静态变量外),所有的内存都是“脏的”;而类类型则会为每个元素调用默认构造函数进行初始化。

 

注意,在C++11中中间的赋值号可以省略,即 int a[5]{1}; 并且,如果初始化列表为空,如 int a[5]{};,那将初始化所有元素为默认值,即与 int a[5]{0}; 等价

 

 

所以当你想在c++对数组赋初值时用正规方法memset.另外注意memset函数原型虽然是:

void *memset(void *s, int ch, size_t n);

 

但是memset只会取int ch的后8位,也就是一个byte.

 

 

错过了初始化时机(memset的误区)
如果想在数组创建结束后再对其进行初始化,可以使用C函数memset(),但是memset的使用有个大问题,就是它只对char类型的数组管用:
char a[10];

memset(a, 1, 10); // 将每个元素设置为1

如果将上面的a数组换成int或其他类型的,就会出现问题,因为memset的内部实现是以字节为单位进行赋值的,int 类型大于一个字节(假设是4个),数组内存连续,如果有下面代码:
int a[10];
memset(a, 1, sizeof(a));


将只会对前sizeof(a)即40个字节进行赋值1的操作,即给“前5个int”进行了赋值0x01010101的操作,失之毫厘谬以千里!