【轉】c++數組初始化

來源:互聯網
上載者:User

標籤:和我   數列   blog   class   單位   十分   nbsp   net   全域   

 數組初始化列表中的元素個數小於指定的數組長度時,不足的元素補以預設值。

原文: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++數組初始化

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.