c 类的初始化 结构体一定要初始化吗_C++初始化的坑你也遇到过吗?

点击蓝字 关注我们

谈及C++的初始化,我们都知道要在变量定义的时候给它赋初值。确实,在每次定义的时候就初始化不仅可以避免脏数据产生,还能增加代码的可读性。但是,你知道这其中有多少陷阱吗?

陷阱1:默认初始化的坑

请看一下代码,你能知道哪些变量的值是确定的?

int a;void func(){    int b;    static int c;    cout<<"a: "<", b :"<}int main(){    cout<<"main a: "<endl;    func();    return 0;}

打印结果是:

main a: 0a: 0, b :32694, c :0

可以看到,三个变量都没有显式初始化,但a,c都被赋予了默认值,而b是不确定的值。

其实我们可以从《C++Primer》中找到答案:“定义于任何函数体之外的变量被初始化为0,定义于函数体内部的内置类型变量将不被初始化”。所谓定义于函数体之外的变量,其实就是全局变量,这里拓展说一下:

初始化过的全局变量,由编译器将其保存于静态存储区的data段,并且这样的值越多,程序就越大,操作系统会在程序启动时,将全局变量的值复制到data段中,即完成变量的初始化。

未初始化的全局变量,由编译器保存于静态存储区的bss段,并且这样的值不会被使程序变大,操作系统加载程序时才分配相应的内存,并将bass段清0,即完成变量的初始化。

所以,定义在函数体之外的变量,会被赋默认值。

但定义在函数中的变量,是在栈中分配的内存,属于动态存储区,此区操作系统不会帮助你清0,所以此处定义的值都是未定义的。

陷阱2:数组初始化的坑

int buff[10] = {0};for(int i = 0;i<10;i++){    cout<}

这段代码相信大家平时常写,答案很明显,都是0,但实际的原因,真的是因为{0}代表要将每个值设为0吗?

答案是否定的,请看下面的这段代码:

int buff_2[10] = {1};for(int i = 0;i<10;i++){    cout<}

得到的答案是:1,0,0,0,0,0,0,0,0,0,大家注意到了吗?只有第一个值才是1,后面的全是0!

所以,这个坑其实是C++初始化列表的坑,初始化列表的定义中说明,如果初始化列表的数量比定义的数量少,那么未被定义到的值将会被赋予默认值!

陷阱3:memset的坑

char buff[10];memset(buff,0,sizeof(buff));for(int i = 0;i<10;i++){    printf("%d ",buff[i]);}

大家一定会觉得这段代码很简单,没错,打印结果就是都为0,的确很简单,但是,看下接下来的代码:

int buff_2[10];memset(buff_2,1,sizeof(buff_2));  for(int i = 0;i<10;i++){    printf("%d ",buff_2[i]);}

是的,变量的类型变了,打印的结果是:

16843009 16843009 16843009 16843009 16843009 16843009 16843009 16843009 16843009 16843009

是不是觉得很奇怪,接下来,我们把这句:

printf("%d ",buff_2[i]);

改为:

printf("0X%x ",buff_2[i]);

得到的结果是:

0X1010101 0X1010101 0X1010101 0X1010101 0X1010101 0X1010101 0X1010101 0X1010101 0X1010101 0X1010101

是不是感觉很蹊跷?

首先,在我的设备上,int是4字节,所以buff_2总共40字节,memset会对40个1字节赋值0X01,而不是对10个4字节赋值0X01。所以不要用memset对非字符型数组赋初值!

关于C++初始化的坑,你遇到过哪些?欢迎在评论中和我探讨。觉得文章不错,请点赞和在看支持我继续分享好文。谢谢!

End


你们的在看就是对我最大的肯定, 点个在看好吗~
d64384fb40e214fab6fecaf9c34713ff.png
编程学习基地 常回基地看看
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值