C 初始化方式

2021-07-26 18:43:29 字數 2768 閱讀 9291

變數被預設初始化由變數型別和定義變數的位置決定,如果內建型別定義的變數在任何函式體之外即全域性變數,則被預設初始化為相關型別的預設值,如int型預設值為0,如果定義的變數位置在任何函式體之內即區域性變數,則不被初始化,乙個未被初始化的變數是未定義的,將會報錯。

如果使用等號(=)初始化乙個變數,實際上執行的是拷貝初始化,編譯器把等號右側的初始值拷貝到新建立的物件中去。與之相反,如果不使用等號,則執行的是直接初始化。

當初始值只有乙個時,使用直接初始化或拷貝初始化都行。如果用多個值進行初始化的情況,非要用拷貝初始化的方式處理也不是不可以,不過需要顯式地建立乙個(臨時)物件用於拷貝。

string s8=string(10,'c'); //拷貝初始化,s8的內容是cccccccccc。

通常直接初始化和複製初始化僅在低級別優化上存在差異。

對於不支援複製的型別,或者使用explicit建構函式,不能進行複製初始化。

通常情況下,可以只提供vector物件容納的元素數量而不用略去初始值。此時庫會建立乙個值初始化的元素初值,並把它賦給容器中的所有元素,這個初值由vector物件中元素的型別決定。

如果vector物件的元素是內建型別,比如int,則元素初始值自動設為0.如果元素時某種類型別,比如string,則元素由類預設初始化。

vectorivec(10);            //10個元素,每個都初始化為0

vectorsvec(10);      //10個元素,每個都是空string物件

對這種初始化的方式有兩個特殊限制:其一,有些類要求必須明確地提供初始值,如果vector物件中元素的型別不支援預設初始化,我們就必須提供初始的元素值。對這種型別的物件來說,只提供元素的數量而不設定初始值無法完成初始化工作。其二,如果只提供了元素的數量而沒有設定初始值,只能使用直接初始化:

vectorvi=10;  //錯誤,必須使用直接初始化的形式指定向量的大小

這裡的10是用來說明如何初始化vector物件的,我們用它的本意是想建立含有10個值初始化了的元素的vector物件,而非數字10」拷貝「到vector中。因此,此時不宜使用拷貝初始化。

在某些情況下,初始化的真實含義依賴於傳遞初始值時用的是花括號還是圓括號,例如,用乙個整數來初始化vector時,整數的含義可能是vector物件的容量也可能是元素的值。類似的,用兩個整數來初使化vector時,這兩個整數可能乙個是vector物件的容量,另乙個是元素的初值,也可能它們是容量為2的vector物件中兩個元素的初值。通過使用花括號或圓括號可以區分上述這些含義:

vectorv1(10);//v1有10個元素,每個的值都是0

vectorv2;//v2有1個元素,該元素的值時10

vectorv3(10,1);//v3有10個元素,每個的值都是1

vectorv4; //v4有兩個元素,值分別是10,1

如果用圓括號,可以說提供的值是用來構造vector物件的。例如,v1的初始值說明了vector物件的容量;v3的兩個初始值則分別說明了vector物件的容量和元素的初值。

如果用的是花括號,可以表述成我們想列表初始化該vector物件。也就是說,初始化過程會盡可能地把花括號內的值當成是元素初始值的列表來處理,只有在無法執行列表初始化時才會考慮其他初始化方式。在上例中,給v2和v4提供的初始值都作為元素的值,所以它們都會執行列表初始化,vector物件v2包含乙個元素而vector物件v4包含兩個元素。

另一方面,如果初始化時使用了花括號的形式但是提供的值又不能用來列表初始化,就要考慮用這樣的值來構造vector物件了。例如,要想列表初始化乙個含有string物件的vector物件,應該提供能賦給string物件的初值。此時不難區分到底是要列表初始化vector物件的元素還是用給定的容量值來構造vector物件:

vectorv5;  //列表初始化,v5有乙個元素

vectorv6("hi");//錯誤,不能使用字串字面值構造vector物件

vectorv7(10);  //v7有10個預設初始化的元素

vectorv8; //v8有10個值為」hi「的元素

預設情況下,動態分配的物件時預設初始化的,這意味著內建型別或組合型別的物件的值時未定義的,而類型別物件將預設建構函式進行初始化:

string *ps=new string;  //初始化為空string

int *pi =new int;   //pi指向乙個未初始化的int

我們可以使用直接初始化方式來初始化以動態分配的物件。我們可以使用傳統的構造方式,在新標準下,也可以使用列表初始化(使用花括號):

int *pi=new int(1024);  //pi指向的物件的值為1024

string *ps=new string(10,'9');   //*派生為「9999999999」

//vector有10個元素,值依次從0-9

vector*pv=new vector;

也可以對動態分配的物件進行值初始化,只需在型別名之後跟一對空括號即可:

string *ps1=new string ;//預設初始化為空string

string *ps=new string(); //值初始化為空string

int *pi1=new int;   //預設初始化;*pi1的值未定義

int *pi2=new int(); //值初始化為0;*pi2的值為0

對於定義了自己的建構函式的類型別來說,要求值初始化是沒有意義的;不管採用什麼方式,物件都會通過預設建構函式來初始化。但對於內建型別,兩種形式的差別就大了;值初始化的內建型別物件有著良好定義的值,而預設初始化的物件的值則是未定義的。類似的,對於類中那些依賴於編譯器合成的預設建構函式的內建型別成員,如果它們未在類內初始化,那麼它們的值也是未定義的。

C語言陣列初始化方式

一維陣列初始化 初始化方法1 int arr 5 定義了乙個長度是5的陣列,並給每個元素賦值 初始化方法2 int arr 5 給下標為0和1的元素賦了初值,剩餘未初始化的元素,預設值都是0 初始化方法3 常用 int arr 5 初始化乙個全部元素為0的陣列,通常這個方法在清0陣列時使用 初始化方...

C 初始化vector物件的方式

初始化vector物件的方式 vectorv1 v1是乙個空vector,他的元素型別為t,執行預設初始化 vectotv2 v1 v2中包含v1所有元素的副本 vectotv2 v1 等價於v2 v1 vectotv3 n,val v3包含了n個重複的元素,每個元素的值都是val vectotv4...

c 類物件初始化方式總結

在 inside the c object model 一書中談到copy constructor的構造操作,有三種情況下,會以乙個object的內容作為另乙個object的初值 第一種情況 xx aa a 第二種情況 xx aa a 第三種情況 extern fun xx aa fun a 函式呼...