【C++】變量(三) 變量的初始化

前面介紹了什麼是變量,以及變量的命名與定義,現在我們來了解一下變量的初始化。

 我們都知道,在定義一個變量時,需要明確它的類型和變量名,其實,有時候我們也要爲變量設定一個初始值。這樣在變量定義時就已被賦值的變量,就是初始化的變量,這個賦值操作稱爲初始化。

C++語言支持兩種初始化的格式:copy-initialization(複製初始化)和direct-initialization(直接初始化)。複製初始化在語句中使用等號;直接初始化則將初始值寫在小括號內。如下,爲ival賦值1024:

int ival(1024);  //direct-initialization

int ival=1024;   //copy-initialization

在C++程序的編寫中,直接初始化比複製初始化的使用要更加靈活。

很多人將變量的初始化看做賦值的一種,但是在C++中這是兩個不同的操作符(原書觀點)。在其他的語言中,這種區別是很少見的,並且是可以不考慮的。儘管這樣,在C++中也要很複雜的程序編寫中才會體現出初始化和賦值的區別。

—————————————————————————————————————————————————

多重初始化程序的應用

 當我們初始化一個內置數據類型的變量時,我們要做的只有:提供一個值,別且把這個值複製到被定義的變量中。對於內置數據類型的變量,直接初始化和複製初始化只有很小的區別。但是,對於類類型的變量,我們只能用直接初始化的方式來進行變量的初始化。爲了理解這點,我們需要先了解下類對於初始化操作的控制。

  每一個類都是由一個或者多個元函數(成員函數)組成,這些元函數恰恰影響了類類型變量的初始化。這些決定類類型變量初始化的元函數通常稱爲構造函數(constructor)。像其他的函數一樣,構造函數也擁有很多的參數(argument)。每個類都會定義一些構造函數,這些構造函數必須包含不同數目或者類型的參數。下面我們來簡單看看string類以便於我們理解。

string類是定義成庫函數並且可以作用於變化長度的字符串的類。爲了使用string類,我們必須include這個類的標題,像IO類型,string類是定義在std的命名空間的。

sting類定義了一些構造函數,這給了我們很多途徑去初始化string。其中一種就如複製一個字符串常量:

#include <string>

//  alternative ways to initialize string from a character string literal

std::string titleA="C++ Primer, 4th Ed.";

std::string titleB("C++ Primer, 4th Ed.");

 在這個例子中,兩種初始化操作都是合法的,它們都創建了一個初始值是特定字符串常量的sting變量。不僅僅是常量,我們也可以通過數量和字符來初始化sting,這樣做可以創建一個包含重複一定數量的字符的string:

std::string all_nines(10, '9');  //all_nines="9999999999"

在這個例子中,我們只能通過直接初始化來初始化all_nines,用複製初始化來進行多重初始化程序的操作。

—————————————————————————————————————————————————

初始化多個變量

 如同定義一個一樣,在定義多個變量時,每個變量一般都有其自己的初始化程序。在定義變量的時候,變量名的後面加上初始化的變量值,使得這個變量更加直觀。在命名語句中,可能同時存在初始化的和非初始化的變量,而且複製初始化和直接初始化可以混合使用。如下:

#include <string>

double salary=9999.99,

       wage(salary+0.01);

int interval,

    month=8, day=7, year=1995;

std::string title ("C++ Primer, 4th Ed."),

            publisher="A-W";

任何表達式都可以用作變量的初始化,包括函數的返回值。如下:

double price=109.99, discount=0.16;

double sale_price=apply_discount(price, discount);

 在這個例子中,apply_discount是一個包含兩個double型參數並且返回值是double型的函數,我們可以把計算所得apply_discount的返回值來初始化sale_price這個變量。

—————————————————————————————————————————————————

變量的初始化潛規則

在定義一個變量時,如果我們沒有進行初始化操作,系統有時候會幫我們完成初始化。至於初始化的值,主要取決於變量的類型以及被定義的位置。

不管怎樣,在函數外定義的變量都被初始化爲0。而如果是在函數體內定義的內置型變量,通常是未初始化的。把任何未初始化變量當做左值來使用的賦值行爲都是未定義的行爲,隨之引起的錯誤很難被發現。所以這種未定義的行爲實不可取的。

—————————————————————————————————————————————————

類類型變量的初始化

 每個類都會定義它的對象的初始化方式,它通過定義不同的構造函數來控制變量的初始化。例如,在string類中至少有兩個構造函數,一個使我們可以初始化爲字符串常量,另一個使我們可以初始化爲字符或者是數量。

類同樣定義了初始化程序對於被定義的變量類型不可用的結果,這是通過定義默認構造函數(default constructor)來實現的。之所以稱爲默認構造函數,是因爲當變量沒有被初始化的時候,這個函數是默認運行的,而且不管這個變量是在哪裏被定義的。

 很多的類都會定義默認構造函數,如果一個類定義了默認構造函數的話,我們有時就不需要一對一的對變量進行初始化操作。例如,string類型定義了一個默認構造函數,使得“string”稱爲一個空的字符串常量:

std::string empty;  //empty is the empty string; empty=""

對於那些沒有定義默認構造函數的類,我們必須針對每個變量進行初始化操作。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章