1. 程式人生 > >宣告、定義、初始化、賦值

宣告、定義、初始化、賦值

變數的定義形式:

首先是型別說明符,隨後緊跟由一個或者多個變數名組成的類別,其中變數名以逗號隔開,最後以分號結束。

例子:int sum,value,unsold;

struct GraphNode{
    int label;
    vector<GraphNode*> neighbors;
    GraphNode(int x):label(x){};
};/*expected ';' after struct definition*/

同理:類的定義後面也要加;

class solution{};

何為物件?

答:物件是具有某種資料型別的記憶體空間。

初始值:

當物件在建立時獲得一個特定的值,我們說這個物件就被初始化(initialized)。(用於初始化變數的值可以使任意複雜的表示式)

WARNING:在c++語言中,初始化和賦值是兩個完全不同的操作,初始化不是賦值。

初始化和賦值的區別:

初始化:建立變數時賦予一個初始值;賦值:把物件當前的值擦掉,而以一個新值來替代。

c++11新標準的部分,用花括號來初始化變數(比如 int un_sold{0};)得到全面應用,而在此之前,這種初始化形式在某些受限的場合使用(比如vector,vector<string> articles{"a","an","the"};  這種初始化形式叫做列表初始化),不過現在無論是初始化物件,還是某些時候為物件賦新值都可以使用這樣一組由花括號括起來的初始值了。

注意:當使用內建型別變數時候,如果存在丟失資訊的風險,編譯器將會報錯:

long double ld = 3.1451234;

int a{ld};//錯誤:轉換未執行。

int c(ld);//正確,但是丟失資訊。

預設初始化:如果定義變數時沒有指定的值,則變數被預設初始化(default initialized)。

如果內建屬性變數未被顯示初始化,它的值由定義的位置決定:

定義於任何函式體之外的變數被初始化為0;定義在函式體內部的內建型別變數將不被初始化(uninitialized)。

為什麼一定要初始化(沒有初始化的後果):

一個未被初始化的內建屬性變數的值是未定義的,如果試圖拷貝或者以其他形式訪問

此類值將引發錯誤。

每個類各自決定其初始化物件的方式。而且,是否允許不經初始化就定義物件也由類自己決定。如果類允許這種行為,它將決定物件的初始值到底是什麼。

絕大多數類都支援無須初始化而定義物件,這樣的類(預設建構函式)提供了一個合適的預設值。

例如:string類規定沒有指定初始值則生成一個空串。

string empty;//empty非顯示的初始化為一個空串。

sales_item item;

一些類要求每個物件都顯示初始化,如果建立一個該類物件而未對其做明確的初始化操作,將引發錯誤。

NOTE:定義於函式體內的內建型別的物件沒有初始化,則其值未定義。

類的物件如果沒有顯示的初始化,則其值由類確定。

TIP:未初始化的變數含有一個不確定的值,會用未初始化變數的值是一種錯誤的並且很難除錯的變成行為。

建議初始化每一個內建型別的變數。

 

變數宣告和定義的關係

為了支援分離式編譯,c++語言將宣告和定義區分來。

變數宣告規定了變數的型別和名字;

變數的定義規定了變數的型別和名字,還申請儲存空間,也可能會為變數賦一個初始值。

如果 想申明一個變數並不是定義它,則可以新增external關鍵字。

extern int i ;//宣告並非定義i

int j ;//宣告並且定義j


任何包含了顯示初始化的宣告都會成為定義。

extern double pi = 3.1415;//定義

如果要在多個檔案中使用同一個變數,就必須將宣告和定義分離,並且變數定義只能出現在一個檔案之中,其他用到該變數的檔案必須對其進行申明。變數可以宣告多次,但是隻可以定義一次。

 

函式宣告和函式的定義

函式的宣告和定義非常類似,唯一的區別就是函式宣告無需函式體,用一個分號代替就可以。

int value(); //函式宣告

int value(){} //函式定義

函式三要素(返回型別,函式名,形參型別)描述了函式的介面,說明了呼叫該函式所需要的全部資訊,函式宣告也稱作函式原型(function prototype)

 

總結:變數(函式)的宣告都放在標頭檔案之中,在原始檔中定義。