c++與c中的數(shù)組初始化默認值如何為0
c++與c中的數(shù)組初始化默認值如何為0
做全局變量
int sum[1000006];//初始化設默認值為0
做局部變量
默認值只能設為0,且只有在初始化時,才能設為0(sum[100]={0};這么寫就是錯的);
如果設為1,則只是sum[0]是1,其他默認全為0;
int sum[100]={0};//只能設為0
遍歷賦值
實際意思和循環(huán)賦值0,是一樣的,只不過這個是庫封裝好了的方法。
#include <cstring>//必須引用 memset(sum,0,sizeof(sum));
c++與c數(shù)組初始化的一些誤區(qū)
以前我這樣初始化一個數(shù)組,并自我感覺良好:
int a[5] = { 0 }; // 全部初始化為0
這種簡單的寫法讓我非常爽,于是我又想把數(shù)組全部初始化為1:
int a[5] = { 1 }; // 我想全部初始化為1
直到十分鐘前,我都以為這句代碼確實能夠?qū)ⅲ祩€元素全部初始化為1,但事實跟我想的完全不同!(基礎的東西革命的本錢,疏漏不得啊)
全部初始化為0的那行代碼確實是沒問題的,可以正常工作。問題就出在想把數(shù)組全部初始化成一個非0的數(shù),即非默認值,是行不通的(查看內(nèi)存發(fā)現(xiàn),只有數(shù)組的第一個元素被初始化為1,其他全為0)。這倒不是因為編譯器對初始化為0給了個后門,而是因為一條基本語法規(guī)則:
數(shù)組初始化列表中的元素個數(shù)小于指定的數(shù)組長度時,不足的元素補以默認值。
對于基本類型int來說,當然就是補int()即0了。再看一下非基本類型的數(shù)組:
string a[5] = { "foo" };
有了上面的規(guī)則,就很容易知道其實相當于:
string a[5] = { "foo", "", "", "", "" };
即后面4個元素調(diào)用了string的默認構(gòu)造函數(shù)進行的初始化,而第一個則調(diào)用的string::string(const char*)進行的初始化。
還有一個區(qū)別:
int a[5]; string a[5];
如果不明確指出初始化列表,那么基本類型是不會被初始化的(除全局變量和靜態(tài)變量外),所有的內(nèi)存都是“臟的”;而類類型則會為每個元素調(diào)用默認構(gòu)造函數(shù)進行初始化。
注意,在C++11中中間的賦值號可以省略,即 int a[5]{1}; 并且,如果初始化列表為空,如 int a[5]{},那將初始化所有元素為默認值,即與 int a[5]{0}; 等價
動態(tài)數(shù)組的初始化
說完了棧中的數(shù)組的初始化,我發(fā)現(xiàn)new一個數(shù)組和其又有一些不同:
int* a = new int[5]; string* a = new string[5]; int* a = new int[5] { 0 }; string* a = new string[5] { "foo" };
上面幾行代碼遵循棧中數(shù)組的初始化規(guī)則,除此之外這里還有一個新語法:
int* a = new int[5]();
注意后面的一對圓括號,它的意思是使用默認值初始化整個數(shù)組,所以對于類類型來說,new string[5] 與 new string[5]()是等價的,都會調(diào)用默認構(gòu)造函數(shù)進行初始化;但是對于基本類型就不同了,new int[5]根本不會初始化,而new int[5]() 則會使用int()的值即0進行初始化。
看到這對圓括號,我想它該不會是元素的構(gòu)造函數(shù)的參數(shù)列表吧,那么我可能會想將數(shù)組全部初始化為1:new int[5](1); 看起來很合理,但其實不行。事實上這對圓括號不是數(shù)組元素的構(gòu)造參數(shù), 可能是整個數(shù)組的,它有三個重載版本:
看起來像是常引用、右值引用、和默認版本。所以假如已經(jīng)有一個相同大小的數(shù)組b,試著用b來初始化a:
int* a = new int[5](b);
結(jié)果編譯出錯,提示
error C3074: an array cannot be initialized with a parenthesized initializer
看來這個括號的作用和我想的不一樣,其實也應該看出來的,要是是用另一個數(shù)組初始化的話那么參數(shù)應該是const int (&)[5] 而不是 const int [5] &,而且后者好像是一個錯誤的類型。這個問題暫時無解。
錯過了初始化時機(memset的誤區(qū))
如果想在數(shù)組創(chuàng)建結(jié)束后再對其進行初始化,可以使用C函數(shù)memset(),但是memset的使用有個大問題,就是它只對char類型的數(shù)組管用:
char a[10]; memset(a, 1, 10); ? ?// 將每個元素設置為1
如果將上面的a數(shù)組換成int或其他類型的,就會出現(xiàn)問題,因為memset的內(nèi)部實現(xiàn)是以字節(jié)為單位進行賦值的,int 類型大于一個字節(jié)(假設是4個),數(shù)組內(nèi)存連續(xù),如果有下面代碼:
int a[10]; memset(a, 1, sizeof(a));
將只會對前sizeof(a)即 40個字節(jié)進行賦值1的操作,即給“前5個int”進行了賦值0x01010101的操作,失之毫厘謬以千里!
如果實在想再初始化,那么老老實實循環(huán)賦值吧。
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
C++標準庫中sstream與strstream的區(qū)別詳細解析
以下是對C++標準庫中sstream與strstream的區(qū)別進行了詳細的分析介紹,需要的朋友可以過來參考下2013-09-09C語言數(shù)據(jù)結(jié)構(gòu)之順序數(shù)組的實現(xiàn)
這篇文章主要介紹了C語言數(shù)據(jù)結(jié)構(gòu)之順序數(shù)組的實現(xiàn)的相關資料,這里提供實現(xiàn)實例,希望通過本文能幫助到大家,需要的朋友可以參考下2017-08-08VisualStudio Community2019在安裝的過程中無法進入安裝界面的解決方法
這篇文章主要介紹了VisualStudio Community2019在安裝的過程中無法進入安裝界面的解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-03-03C++?OpenCV技術(shù)實戰(zhàn)之身份證離線識別
OpenCV身份證離線識別技術(shù)的主要技術(shù)就是通過OpenCV找到身份證號碼區(qū)域,然后通過OCR進行數(shù)字識別該區(qū)域的截圖即可得到身份證號碼。感興趣的可以了解一下2021-12-12C++實現(xiàn)將長整型數(shù)轉(zhuǎn)換為字符串的示例代碼
這篇文章主要介紹了C++實現(xiàn)將長整型數(shù)轉(zhuǎn)換為字符串的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-04-04