天天看點

c++ 初始化清單_C++ 初始化的坑,你也遇到過嗎?

(給程式員的那些事加星标)

轉自:CPP開發者

談及 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<endl;}
           

這段代碼相信大家平時常寫,答案很明顯,都是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++初始化的坑,你遇到過哪些?。覺得文章不錯,請點贊和在看支援我繼續分享好文。謝謝!

c++ 初始化清單_C++ 初始化的坑,你也遇到過嗎?

點贊和在看就是最大的支援❤️