初探C/C++ {0}式 初始化

本文探讨了在VC++2010环境下初始化数组时,编译器如何选择不同的汇编指令来优化性能。对于小数组,编译器采用逐个元素赋值的方式;对于较大数组,则调用memset进行批量初始化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

就用一个很简单的程序试试

int  main()
{
    int  a[10] = {0};
    return  0;
}

 

在int a[10] = {0};这行设置断点,

F5 开始调试

Alt+8 调出汇编标签

 

关键汇编如下:

     4:     int  a[10] = {0};
012B8238  mov          dword  ptr  [ebp -30h],0  
012B823F  xor          eax ,eax   
012B8241  mov          dword  ptr  [ebp -2Ch],eax   
012B8244  mov          dword  ptr  [ebp -28h],eax   
012B8247  mov          dword  ptr  [ebp -24h],eax   
012B824A  mov          dword  ptr  [ebp -20h],eax   
012B824D  mov          dword  ptr  [ebp -1Ch],eax   
012B8250  mov          dword  ptr  [ebp -18h],eax   
012B8253  mov          dword  ptr  [ebp -14h],eax   
012B8256  mov          dword  ptr  [ebp -10h],eax   
012B8259  mov          dword  ptr  [ebp -0Ch],eax   

 

额,一看之下是不是傻了眼?

难道{0}的作用只是简单的一个个将元素赋值?

而且SB式的一个个mov?

不是吧……

将数组大小改大一点看看,比如30

再看一下汇编代码:

     4:     int  a[30] = {0};
011D8238  mov          dword  ptr  [ebp -80h],0  
011D823F  push         74h  
011D8241  push         0  
011D8243  lea          eax ,[ebp -7Ch]  
011D8246  push         eax   
011D8247  call         @ILT+1180(_memset) (11D64A1h)  
011D824C  add          esp ,0Ch  

 

这次没那么SB了,通过调用_memset(跟进去,其实还是调用memset)

而且是从第二个元素的地址开始的,第一个已经赋0了

74h(16) => 116(10) = 29 * 4 (一个int 4字节,即32位)

 

大概也就这样了,编译器先判断数组长度有没有大于默认的,

大于就使用memset,不然一个个mov……

 

这就好办了,以后知道调用的函数绝对的会先清零那数组的话,

就不要写{0}了,免得又浪费那么多CPU周期

不过就现在CPU来说,写上去或者又是一种保证,反正CPU速度那么牛了

不在意那么点东东

 

再试了下char类型,差不多的了

 

测试环境:VC++ 2010 (Debug) + Windows 7 Ultimate SP1

(Release貌似又不是这样,下回有空再玩玩)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值