自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

C++ 初始化的坑,你也遇到過嗎?

新聞 前端
談及 C++ 的初始化,我們都知道要在變量定義的時候給它賦初值。確實,在每次定義的時候就初始化不僅可以避免臟數(shù)據(jù)產(chǎn)生,還能增加代碼的可讀性。

 談及 C++ 的初始化,我們都知道要在變量定義的時候給它賦初值。確實,在每次定義的時候就初始化不僅可以避免臟數(shù)據(jù)產(chǎn)生,還能增加代碼的可讀性。但是,你知道這其中有多少陷阱嗎?

[[345626]]

陷阱1:默認(rèn)初始化的坑

請看一下代碼,你能知道哪些變量的值是確定的?

  1. int a; 
  2.  
  3. void func() 
  4.  
  5.  
  6. int b; 
  7.  
  8. static int c; 
  9.  
  10. cout<<"a: "<<a<<", b :"<<b<<", c :"<<c<<endl; 
  11.  
  12.  
  13. int main() 
  14.  
  15.  
  16. cout<<"main a: "<<a<<endl; 
  17.  
  18. func(); 
  19.  
  20. return 0
  21.  

打印結(jié)果是:

  1. main a: 0 
  2.  
  3. a: 0, b :32694, c :0 

可以看到,三個變量都沒有顯式初始化,但a,c都被賦予了默認(rèn)值,而b是不確定的值。

其實我們可以從《C++Primer》中找到答案:“定義于任何函數(shù)體之外的變量被初始化為0,定義于函數(shù)體內(nèi)部的內(nèi)置類型變量將不被初始化”。所謂定義于函數(shù)體之外的變量,其實就是全局變量,這里拓展說一下:

初始化過的全局變量,由編譯器將其保存于靜態(tài)存儲區(qū)的data段,并且這樣的值越多,程序就越大,操作系統(tǒng)會在程序啟動時,將全局變量的值復(fù)制到data段中,即完成變量的初始化。

未初始化的全局變量,由編譯器保存于靜態(tài)存儲區(qū)的bss段,并且這樣的值不會被使程序變大,操作系統(tǒng)加載程序時才分配相應(yīng)的內(nèi)存,并將bass段清0,即完成變量的初始化。

所以,定義在函數(shù)體之外的變量,會被賦默認(rèn)值。

但定義在函數(shù)中的變量,是在棧中分配的內(nèi)存,屬于動態(tài)存儲區(qū),此區(qū)操作系統(tǒng)不會幫助你清0,所以此處定義的值都是未定義的。

陷阱2:數(shù)組初始化的坑

  1. int buff[10] = {0}; 
  2.  
  3. for(int i = 0;i<10;i++) 
  4.  
  5.  
  6. cout<<buff[i]<<endl; 
  7.  

這段代碼相信大家平時常寫,答案很明顯,都是0,但實際的原因,真的是因為{0}代表要將每個值設(shè)為0嗎?

答案是否定的,請看下面的這段代碼:

  1. int buff_2[10] = {1}; 
  2.  
  3. for(int i = 0;i<10;i++) 
  4.  
  5.  
  6. cout<<buff_2[i]<<","
  7.  

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

所以,這個坑其實是C++初始化列表的坑,初始化列表的定義中說明,如果初始化列表的數(shù)量比定義的數(shù)量少,那么未被定義到的值將會被賦予默認(rèn)值!

陷阱3:memset的坑

  1. char buff[10]; 
  2.  
  3. memset(buff,0,sizeof(buff)); 
  4.  
  5. for(int i = 0;i<10;i++) 
  6.  
  7.  
  8. printf("%d ",buff[i]); 
  9.  

大家一定會覺得這段代碼很簡單,沒錯,打印結(jié)果就是都為0,的確很簡單,但是,看下接下來的代碼:

  1. int buff_2[10]; 
  2.  
  3. memset(buff_2,1,sizeof(buff_2)); 
  4.  
  5. for(int i = 0;i<10;i++) 
  6.  
  7.  
  8. printf("%d ",buff_2[i]); 
  9.  

是的,變量的類型變了,打印的結(jié)果是:

  1. 16843009 16843009 16843009 16843009 16843009 16843009 16843009 16843009 16843009 16843009 

是不是覺得很奇怪,接下來,我們把這句:

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

改為:

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

得到的結(jié)果是:

  1. 0X1010101 0X1010101 0X1010101 0X1010101 0X1010101 0X1010101 0X1010101 0X1010101 0X1010101 0X1010101 

是不是感覺很蹊蹺?

首先,在我的設(shè)備上,int是4字節(jié),所以buff_2總共40字節(jié),memset會對40個1字節(jié)賦值0X01,而不是對10個4字節(jié)賦值0X01。所以不要用memset對非字符型數(shù)組賦初值!

 

責(zé)任編輯:張燕妮 來源: CPP開發(fā)者
相關(guān)推薦

2021-08-29 18:36:17

MySQL技術(shù)面試題

2020-11-08 14:38:35

JavaScript代碼開發(fā)

2009-07-23 15:07:32

2017-07-14 09:29:45

AndroidWebview

2019-10-28 14:07:29

研發(fā)管理技術(shù)

2011-04-26 09:22:05

SQLite

2021-04-04 22:31:26

白帽子廠商漏洞

2023-03-13 07:41:34

分頁查詢數(shù)據(jù)排序

2021-05-27 09:27:35

開發(fā)技能緩存

2018-04-25 10:57:00

AIX報錯vios

2024-03-13 08:52:43

C++初始化方式

2023-11-12 23:08:17

C++初始化

2020-09-24 10:49:09

iOSiPadOSBug

2019-12-05 08:44:20

MybatisSQL場景

2024-03-18 08:14:07

SpringDAOAppConfig

2022-10-20 18:00:59

OCP模型參數(shù)

2021-12-26 14:32:11

緩存數(shù)據(jù)庫數(shù)據(jù)

2017-09-07 15:23:21

神經(jīng)網(wǎng)絡(luò)數(shù)據(jù)網(wǎng)絡(luò)

2011-06-09 14:13:06

C++JAVA缺省初始化

2010-02-06 14:40:50

C++初始化和賦值
點贊
收藏

51CTO技術(shù)棧公眾號