c++与c中的数组初始化默认值如何为0

 更新时间:2023年08月09日 09:26:22   作者:25zhixun  
这篇文章主要介绍了c++与c中的数组初始化默认值如何为0问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

c++与c中的数组初始化默认值如何为0

做全局变量

int sum[1000006];//初始化设默认值为0

做局部变量

默认值只能设为0,且只有在初始化时,才能设为0(sum[100]={0};这么写就是错的);

如果设为1,则只是sum[0]是1,其他默认全为0;

int sum[100]={0};//只能设为0

遍历赋值

实际意思和循环赋值0,是一样的,只不过这个是库封装好了的方法。

#include <cstring>//必须引用
memset(sum,0,sizeof(sum));

c++与c数组初始化的一些误区

以前我这样初始化一个数组,并自我感觉良好:

int a[5] = { 0 };    // 全部初始化为0

这种简单的写法让我非常爽,于是我又想把数组全部初始化为1:

int a[5] = { 1 };    // 我想全部初始化为1

直到十分钟前,我都以为这句代码确实能够将5个元素全部初始化为1,但事实跟我想的完全不同!(基础的东西革命的本钱,疏漏不得啊)

全部初始化为0的那行代码确实是没问题的,可以正常工作。问题就出在想把数组全部初始化成一个非0的数,即非默认值,是行不通的(查看内存发现,只有数组的第一个元素被初始化为1,其他全为0)。这倒不是因为编译器对初始化为0给了个后门,而是因为一条基本语法规则:

数组初始化列表中的元素个数小于指定的数组长度时,不足的元素补以默认值。

对于基本类型int来说,当然就是补int()即0了。再看一下非基本类型的数组:

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

有了上面的规则,就很容易知道其实相当于:

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}; 等价

动态数组的初始化

说完了栈中的数组的初始化,我发现new一个数组和其又有一些不同:

int* a = new int[5];
string* a = new string[5];
int* a = new int[5] { 0 };
string* a = new string[5] { "foo" };

上面几行代码遵循栈中数组的初始化规则,除此之外这里还有一个新语法:

int* a = new int[5]();

注意后面的一对圆括号,它的意思是使用默认值初始化整个数组,所以对于类类型来说,new string[5] 与 new string[5]()是等价的,都会调用默认构造函数进行初始化;但是对于基本类型就不同了,new int[5]根本不会初始化,而new int[5]() 则会使用int()的值即0进行初始化。

看到这对圆括号,我想它该不会是元素的构造函数的参数列表吧,那么我可能会想将数组全部初始化为1:new int[5](1); 看起来很合理,但其实不行。事实上这对圆括号不是数组元素的构造参数, 可能是整个数组的,它有三个重载版本:

看起来像是常引用、右值引用、和默认版本。所以假如已经有一个相同大小的数组b,试着用b来初始化a:

int* a = new int[5](b);

结果编译出错,提示

error C3074: an array cannot be initialized with a parenthesized initializer

看来这个括号的作用和我想的不一样,其实也应该看出来的,要是是用另一个数组初始化的话那么参数应该是const int (&)[5] 而不是 const int [5] &,而且后者好像是一个错误的类型。这个问题暂时无解。

错过了初始化时机(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的操作,失之毫厘谬以千里!

如果实在想再初始化,那么老老实实循环赋值吧。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • C++联合体union用法实例详解

    C++联合体union用法实例详解

    这篇文章主要介绍了C++联合体union用法,较为详细的分析了C++中联合体的概念、实用技巧及相关注意事项,需要的朋友可以参考下
    2015-05-05
  • C语言从txt文件中逐行读入数据存到数组中的实现方法

    C语言从txt文件中逐行读入数据存到数组中的实现方法

    下面小编就为大家带来一篇C语言从txt文件中逐行读入数据存到数组中的实现方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-12-12
  • opencv实现角点检测

    opencv实现角点检测

    这篇文章主要为大家详细介绍了opencv实现角点检测,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • MFC实现字幕滚动效果

    MFC实现字幕滚动效果

    这篇文章主要为大家详细介绍了MFC实现滚动字幕,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-05-05
  • C语言递归:汉诺塔问题分析

    C语言递归:汉诺塔问题分析

    这篇文章主要介绍了C语言递归:汉诺塔问题分析的相关资料,需要的朋友可以参考下
    2023-01-01
  • 4组C语言中顺序读写文件的函数分享

    4组C语言中顺序读写文件的函数分享

    这篇文章主要为大家详细介绍了4组C语言中实现顺序读写文件的函数,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-03-03
  • C语言字符串转换为Python字符串的方法

    C语言字符串转换为Python字符串的方法

    这篇文章主要介绍了C语言字符串转换为Python字符串的方法,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-07-07
  • 快速了解C语言静态关键字static的作用

    快速了解C语言静态关键字static的作用

    这篇文章主要介绍了C语言中静态关键字static的作用,对大家学习C语言非常有帮助,有需求的小伙伴可以参考下
    2020-05-05
  • C++求1到n中1出现的次数以及数的二进制表示中1的个数

    C++求1到n中1出现的次数以及数的二进制表示中1的个数

    这篇文章主要介绍了C++求1到n中1出现的次数以及数的二进制表示中1的个数,两道基础的算法题目,文中也给出了解题思路,需要的朋友可以参考下
    2016-02-02
  • C语言堆栈帧的介绍与创建

    C语言堆栈帧的介绍与创建

    这篇文章主要给大家介绍了关于C语言堆栈帧的相关资料,堆栈帧 (stack frame)( 或活动记录 (activation Tecord)) 是一块堆栈保留区域,用于存放被传递的实际参数、子程序的返回值、局部变量以及被保存的寄存器,需要的朋友可以参考下
    2021-08-08

最新评论