(转载)你好,C++(7)第三部分 C++世界众生相 3.2.1 变量的定义与初始化
你好,C++(7)第三部分 C++世界眾生相 3.2.1 變量的定義與初始化
? ? ? ? ? ? ? ? ? ? ?
第3部分
C++世界眾生相
在聽過了HelloWorld.exe的自我介紹,完成了與C++世界的第一次親密接觸后,大家是不是都急不可待地想要一試身手,開始編寫C++程序了呢?程序的兩大任務(wù)是描述數(shù)據(jù)和處理數(shù)據(jù)。那么,接下來我們將面臨的第一個問題就是:如何在C++中描述數(shù)據(jù)?
3.1? C++中的數(shù)據(jù)類型
編程就是使用程序設(shè)計(jì)語言來描述和表達(dá)現(xiàn)實(shí)世界。現(xiàn)實(shí)世界中有很多客觀存在的事物,例如,電腦、人、汽車等。我們總是用各種數(shù)據(jù)來描述這些事物的不同屬性,比如,我們用一個字符串“ChenLiangqiao”來描述某個人的名字;用一個數(shù)字“175”來描述他的身高。而其中的某些數(shù)據(jù)往往可以歸結(jié)為同一類型,比如,描述人的身高和電腦屏幕尺寸的數(shù)據(jù)都是數(shù)值數(shù)據(jù),而描述人的名字和汽車牌照的數(shù)據(jù)都是字符串?dāng)?shù)據(jù)。對應(yīng)的,在C++中,為了描述這些數(shù)據(jù),我們將相同類型的數(shù)據(jù)抽象成某一數(shù)據(jù)類型,然后使用這一數(shù)據(jù)類型定義的變量來表達(dá)這類數(shù)據(jù)。例如,我們將現(xiàn)實(shí)世界中的各種整數(shù)(表示身高的175,表示屏幕尺寸的21)抽象成C++中的int這種數(shù)據(jù)類型,然后用int定義的變量來描述某個具體的整數(shù)數(shù)據(jù)。比如,我們可以定義一個int類型的變量nHeight來表示某個人的身高;定義另外一個int類型的變量nSize來表示某臺電視機(jī)的尺寸。
這里我們也可以看到,相同的數(shù)據(jù)類型(int)可以定義多個不同的變量(nHeight、nSize),分別用于表示多個不同的具體事物(身高、尺寸)。反過來,表示不同事物的多個變量(nHeight、nSize),也可以是同一數(shù)據(jù)類型(int)。這就像現(xiàn)實(shí)世界中的百家姓一樣,姓陳(int)的可以有好多人(nHeight、nSize),而好多人(nHeight、nSize)也都可以姓陳(int)。一個數(shù)據(jù)的數(shù)據(jù)類型,決定了這個數(shù)據(jù)是哪一家的人,而既然是同一家的人,那么這一家人都有著某些相同的特征。比如,它們都占用相同的內(nèi)存字節(jié)數(shù),所能夠表示的數(shù)據(jù)范圍都相同等等。如圖3-1所示。
在C++中,按照所能夠表達(dá)數(shù)據(jù)的復(fù)雜程度,數(shù)據(jù)類型可分為基本數(shù)據(jù)類型和構(gòu)造數(shù)據(jù)類型。
1. 基本數(shù)據(jù)類型
在現(xiàn)實(shí)世界中有很多簡單的數(shù)據(jù),比如某個數(shù)字、某個字符等。為了表達(dá)這些簡單數(shù)據(jù),C++將這些數(shù)據(jù)分門別類地抽象成了多種基本數(shù)據(jù)類型。比如,表示人身高的175、表示電視機(jī)尺寸的21都是整數(shù),C++將這些整數(shù)抽象成int數(shù)據(jù)類型;表示選擇題選項(xiàng)的A、B、C、D都是字符,C++將字符抽象成char數(shù)據(jù)類型。基本數(shù)據(jù)類型是C++中最基礎(chǔ)的數(shù)據(jù)類型,是C++世界最底層的民眾,都具有自我說明的特點(diǎn),不再具有可分性。
2. 構(gòu)造數(shù)據(jù)類型
現(xiàn)實(shí)世界是復(fù)雜的,只使用C++所提供的基本數(shù)據(jù)類型還不能夠完全描述復(fù)雜的現(xiàn)實(shí)世界。比如,我們無法用一個基本數(shù)據(jù)類型的數(shù)據(jù)來描述一個矩形,因?yàn)榫匦斡虚L和寬兩個屬性需要描述。但是我們發(fā)現(xiàn),復(fù)雜事物都是由簡單事物組成的,一個復(fù)雜的事物可以分解成多個簡單事物,而將多個簡單事物進(jìn)行組合,也就構(gòu)成了一個復(fù)雜事物。與現(xiàn)實(shí)世界相對應(yīng),C++中也提供了結(jié)構(gòu)體和類等組合機(jī)制,可以將多個基本數(shù)據(jù)類型組合起來,構(gòu)成一個比較復(fù)雜的構(gòu)造數(shù)據(jù)類型以描述更加復(fù)雜的事物。例如,可以將兩個簡單的基本數(shù)據(jù)類型int組合起來形成一個新的數(shù)據(jù)類型Rect,用來描述更復(fù)雜的矩形。在C++中,可以使用struct關(guān)鍵字來創(chuàng)建一個新的構(gòu)造數(shù)據(jù)類型:
// 創(chuàng)建描述矩形的數(shù)據(jù)結(jié)構(gòu)Rect struct Rect {int m_nLength; // 表示矩形的長 int m_nWidth; // 表示矩形的寬 }; // 使用Rect構(gòu)造數(shù)據(jù)類型定義一個表示矩形的變量r Rect r; r.nLength = 4; // 讓矩形的長為4 r.nWidth = 3; // 讓矩形的寬為3一個構(gòu)造數(shù)據(jù)類型可以分解成若干個“成員”或“元素”。每個“成員”都是一個基本數(shù)據(jù)類型或另一個構(gòu)造數(shù)據(jù)類型。如果我們將基本數(shù)據(jù)類型看成是化學(xué)中的原子的話,那么,構(gòu)造數(shù)據(jù)類型就可以看成是由原子(int)組合而成的分子(Rect)。按照組合的形式不同,C++中的構(gòu)造數(shù)據(jù)類型可以分為4種:①數(shù)組類型;②結(jié)構(gòu)類型;③聯(lián)合類型;④枚舉類型。這些構(gòu)造數(shù)據(jù)類型我們將在稍后的章節(jié)中詳細(xì)介紹。
3.2? 變量和常量
C++世界住滿了各種數(shù)據(jù)量。從本質(zhì)上講,它們都是保存在某個內(nèi)存位置上的數(shù)據(jù)。其中的某些數(shù)據(jù)需要在程序的運(yùn)行過程中發(fā)生變化。比如,表示一個人身高的數(shù)據(jù)175,有可能在程序運(yùn)行過程中變?yōu)?80。同時,程序中還有另外一類數(shù)據(jù)量,它們在整個程序的運(yùn)行過程中始終保持不變。比如表示圓周率的3.14159,在程序運(yùn)行的任何時刻都不會變化。我們將那些在程序運(yùn)行過程中可能會發(fā)生變化的數(shù)據(jù)量稱為變量,而將那些始終保持不變的數(shù)據(jù)量稱為常量。
3.2.1? 變量的定義與初始化
為了保存數(shù)據(jù),我們首先需要為它開辟合適的內(nèi)存空間。同時,對于程序中的變量而言,我們往往需要對其進(jìn)行多次讀寫訪問。為了便于訪問變量,我們往往需要給變量一個名字,然后通過變量名訪問它所代表的數(shù)據(jù)。如果我們想要表達(dá)現(xiàn)實(shí)世界中的某個具體的可變化的數(shù)據(jù),就可以使用這個數(shù)據(jù)所對應(yīng)的數(shù)據(jù)類型,按照如下的語法格式來定義一個變量:
數(shù)據(jù)類型說明符 變量名; // 同時定義相同類型的多個變量 // 不推薦的形式 ,多個變量容易讓人混淆,代碼缺乏可讀性 數(shù)據(jù)類型說明符 變量名1,變量名2,變量名n;變量定義由數(shù)據(jù)類型說明符和變量名兩部分構(gòu)成。數(shù)據(jù)類型是對變量類型的說明,用于指定這個變量是整型、浮點(diǎn)型還是自定義數(shù)據(jù)類型等,因而它也決定了這個變量的一些基本特征,比如占用的內(nèi)存字節(jié)數(shù)、取值范圍等。變量名是用來標(biāo)記變量的符號,就相當(dāng)于變量的名字一樣,我們可以通過變量名對變量所表示的數(shù)據(jù)進(jìn)行讀寫訪問。例如,我們想要在程序中表示一個人的可變化的身高數(shù)據(jù)175,而175這個數(shù)據(jù)的類型是整數(shù),與之相對應(yīng)的C++數(shù)據(jù)類型是int,所以我們選擇int作為變量的數(shù)據(jù)類型。又因?yàn)檫@個變量所表示的是人的身高,所以我們選擇nHeight(n表示這是一個整數(shù),Height表示這是身高數(shù)據(jù))作為變量名:
// 定義一個int類型的變量nHeight,用來表示身高 int nHeight;完成這樣的變量定義后,就相當(dāng)于為即將保存的175數(shù)據(jù)開辟了4個字節(jié)的內(nèi)存空間(int類型的變量在內(nèi)存中占有4個字節(jié)的空間),同時指定了這個變量的名字是nHeight,進(jìn)而可以通過nHeight這個變量名將175身高數(shù)據(jù)保存到內(nèi)存或者是對其進(jìn)行讀寫訪問:
// 通過nHeight寫入數(shù)據(jù) // 將175這個身高數(shù)據(jù)保存到內(nèi)存 nHeight = 175; // 通過nHeight讀取數(shù)據(jù) // 將nHeight變量代表的身高數(shù)據(jù)175顯示到屏幕 cout<<"身高:"<<nHeight<<endl; // 通過變量名將身高數(shù)據(jù)修改為180 nHeight = 180; // 輸出修改后的身高數(shù)據(jù) cout<<"修改后的身高:"<<nHeight<<endl;定義變量時,應(yīng)注意以下幾點(diǎn)。
l? 不能用C++關(guān)鍵字作為變量名。比如常見的bool、for、do、case等關(guān)鍵字(在IDE中顯示為藍(lán)色等特殊顏色)都不能作為變量名;變量名不能以數(shù)字開始。例如,以下變量定義都是錯誤的:
int case; // 錯誤:case是關(guān)鍵字 int 2member; // 錯誤:變量名以數(shù)字開始知道更多:C++中到底有多少關(guān)鍵字?
關(guān)鍵字(keyword)又稱保留字,是C++在整個語言范圍內(nèi)預(yù)先保留的標(biāo)識符。每個C++關(guān)鍵字都有特殊的含義,用以完成某項(xiàng)特定的功能。比如,int表示整數(shù)數(shù)據(jù)類型;for表示定義一個循環(huán)語句;class表示定義一個類等等。因?yàn)殛P(guān)鍵字已經(jīng)擁有預(yù)先定義的含義,所以無法用做標(biāo)識符(變量名、函數(shù)名或類名等)。C++的關(guān)鍵字如下表所示。
表3-1 C++中的關(guān)鍵字
| ? alignas (C++11 啟用) | ? enum for new | ? return using |
這里列出了C++中所有的84個關(guān)鍵字,但其中的大部分關(guān)鍵字我們很少用到。對于這些關(guān)鍵字,我們沒有必要全部掌握。我們只需要掌握其中最常用的一、二十個,至于其他的關(guān)鍵字,需要用到的時候再去查資料就可以了。
l? 允許在一個數(shù)據(jù)類型說明符后同時定義多個相同類型的變量。各變量名之間用逗號(這里的逗號必須是英文逗號)間隔。例如:
// 同時定義三個int類型的變量, // 分別表示學(xué)生的ID(nStuID),年齡(nAge)和身高(nHeight) int nStuID,nAge,nHeight;l? 數(shù)據(jù)類型說明符與變量名之間至少要有一個空格間隔。
l? 最后一個變量名之后必須以“;”結(jié)尾,表示語句的結(jié)束。
l? 變量定義必須放在變量使用之前。換句話說,也就是變量必須先定義后使用。
最佳實(shí)踐:變量定義應(yīng)盡可能地靠近變量使用的位置
我們知道,變量在定義之后才可使用,也就是變量在使用之前必須先被定義。那么,這個“使用之前”到底“前”到什么程度合適呢?是“使用之前”的1行代碼恰當(dāng)還是100行代碼合適?面對這個問題,我們并沒有一個固定的標(biāo)準(zhǔn)答案,但是我們有一個應(yīng)當(dāng)遵循的原則:變量定義應(yīng)盡可能地靠近變量使用的位置。
如果變量定義的位置和變量實(shí)際使用的位置相距太遠(yuǎn),則這中間可能會發(fā)生很多事情。比如,程序可能中途退出,定義的變量并沒有得到使用而白白浪費(fèi);也可能在中間被錯誤地使用而給程序帶來難以發(fā)現(xiàn)的問題。另外一方面,如果兩者相距太遠(yuǎn),我們在使用一個變量的時候,卻難以找到它定義的位置,從而無法輕易地得知這個變量的數(shù)據(jù)類型等基本信息,影響我們對變量的使用。所以,為了避免這些可能存在的麻煩,一個簡單而有效的方法是,盡可能地推遲變量定義的時機(jī),盡可能地靠近其實(shí)際使用的位置。
在定義變量的時候,除了確定變量的數(shù)據(jù)類型之外,另外一個重要的工作就是給變量取一個好名字。一個人如果有個好名字,就很容易給人留下良好而深刻的印象,而變量的名字也一樣。合適的變量名包含跟變量相關(guān)的信息,可以自我解釋,讓人更容易理解和使用,從而提高代碼的可讀性。那么如何給變量取一個合適的名字呢?比較下面這四個變量名:
// 記錄學(xué)生數(shù)量的變量 int nStuNum; int N; int theNumberofStudent; int xssl;這四個變量都是用來表示學(xué)生數(shù)量的。如果要問這四個變量名哪個最好,大家肯定會說第一個變量最好,因?yàn)榈谝粋€變量名一看就知道是用來表示學(xué)生數(shù)量的。而其他幾個,都有各自的缺點(diǎn):第二個太短,不知道這個變量的具體含義;第三個太長,書寫繁瑣;第四個使用漢語拼音的首字母縮寫,更是讓人一頭霧水。
好的變量名可以恰當(dāng)?shù)亟忉屪兞克硎镜囊饬x,無需過多的注釋或文檔,整個代碼就清晰可讀,可以做到“望文生義”。要為變量取一個好名字,通常要遵循某種命名規(guī)則。目前業(yè)界比較流行的命名規(guī)則當(dāng)屬微軟公司提倡的“匈牙利命名法”。在匈牙利命名法中,一個變量名主要由三部分構(gòu)成:
變量名 = 屬性 + 類型 + 對象描述
其中,屬性通常用來對這個變量的一些附加信息進(jìn)行說明。例如,我們通常用“m_”前綴表示這個變量是某個類的成員(member)變量,而使用“g_”前綴表示這是一個全局(global)變量;類型表示這個變量的數(shù)據(jù)類型,通常用各種數(shù)據(jù)類型的縮寫表示,例如我們通常用n表示int類型,用f表示float類型等;而對象描述就是對這個變量含義的說明了,它通常是一個名詞。將這三個部分組合起來,就構(gòu)成了一個完整的變量名,可以表達(dá)豐富的關(guān)于這個變量的信息。例如,某個變量的名字是“m_unAge”,一看變量名就知道這個變量表達(dá)的意義就是:這是某個類的成員變量(m_),它的數(shù)據(jù)類型是unsigned int(un),而它是用于描述這個類的年齡(Age)屬性的。
知道更多:匈牙利命名法中的“匈牙利”是怎么來的?
匈牙利命名法是由一位叫 Charles Simonyi 的匈牙利程序員首先提出的,后來他在微軟公司工作了數(shù)年,因?yàn)檫@種命名法用很少的文字很好地概括了變量的最重要信息,因而受到微軟公司的認(rèn)同并逐漸在微軟內(nèi)部流行起來。又因?yàn)槲④浽跇I(yè)界的強(qiáng)大影響力,匈牙利命名法也開始通過微軟的各種產(chǎn)品和文檔資料向全世界傳播開,逐漸成為業(yè)界最為流行的變量命名方法。對于大部分程序員而言,無論自己使用的是何種開發(fā)語言,或多或少都會使用這種變量命名法。
這種命名法之所以被稱為“匈牙利命名法”,就是為了紀(jì)念這位發(fā)明者所來自的國家。
使用匈牙利命名法,可以在一個變量名內(nèi)表達(dá)豐富的信息,在一定程度上提高了代碼的可讀性。但是它也有一個最大的缺點(diǎn)——繁瑣。有時候,一些過長而又意義不大的前綴為變量名增加了額外的負(fù)擔(dān)。而這也是它并沒有受到全世界所有程序員全都使用的原因。世界上并無所謂最好的命名規(guī)則。在實(shí)踐中,可以根據(jù)業(yè)界流行的一些共性規(guī)則,再結(jié)合項(xiàng)目的實(shí)際情況來制定一種令大多數(shù)項(xiàng)目成員都滿意的命名規(guī)則,并在項(xiàng)目中貫徹實(shí)施。“最合適”的規(guī)則就是“最好”的規(guī)則了。經(jīng)過實(shí)踐的檢驗(yàn),業(yè)界流行的一些共性命名規(guī)則主要有以下幾點(diǎn)。
1. 簡單易懂
變量名應(yīng)當(dāng)直觀,方便拼讀,可望文而生義。變量名最好采用英文單詞或組合,便于記憶和閱讀;切忌使用漢語拼音來命名,因?yàn)檫@樣的變量名,只有你一個人能看懂;程序中的英文單詞不宜太過復(fù)雜,用詞應(yīng)當(dāng)盡量做到地道、準(zhǔn)確。例如,把表示“當(dāng)前數(shù)值”的變量命名為“fNowVal”,雖然能夠表達(dá)變量的含義,但遠(yuǎn)沒有“fCurVal”來得地道。
2. 最短長度,最大信息量
通常,編譯器對變量名的長度沒有限制。一般來說,長名字能更好地表達(dá)變量的含義,所以C++中的變量名長達(dá)十幾個字符也不足為奇。既然沒有限制,那么變量的名字是不是越長越好呢?不見得。只要能夠完整地表達(dá)變量的含義,變量名應(yīng)該越簡單越好。例如,同樣是表示最大值,變量名“max”就要比“maxValueUntilOverflow”好用,因?yàn)樗米疃痰拈L度表達(dá)了最大的信息量。
3. 作用范圍越大,變量名越長
關(guān)于變量名的長度,我們還可以記住這樣一條簡單的規(guī)則:變量名(或者后文將介紹的函數(shù)名等)的長度與它的作用域的大小成正相關(guān)。所謂的作用域,也就是某個標(biāo)識符(變量名或者函數(shù)名)發(fā)生作用的代碼范圍,具體介紹可以參考后繼的7.3.3小節(jié)。換句話說,也就是如果一個變量的作用域比較大,那么在這個作用域內(nèi)的變量就會比較多,為了避免沖突便于區(qū)分,變量名就應(yīng)該比較長。反之亦然。例如,在一個函數(shù)內(nèi)部,我們可以用一個簡單的i來給一個局部變量命名,而在全局范圍內(nèi),再使用i來給一個全局變量命名就不太合適了。
4. 變量名由名詞構(gòu)成
變量表示的是現(xiàn)實(shí)世界中的一個具體事物,其本質(zhì)是一個數(shù)據(jù)實(shí)體,所以變量名的核心應(yīng)該是一個名詞,因而它應(yīng)當(dāng)使用單獨(dú)的一個“名詞”或者“形容詞+名詞”的組合形式。例如:
float fWeight; // 名詞,表示某個人的體重 float fLastWeight; // 形容詞 + 名詞,表示上一次的體重 float fCurWeight; // 形容詞 + 名詞,表示當(dāng)前體重4. 不要使用數(shù)字編號
盡量避免變量名中出現(xiàn)數(shù)字編號,如“Value1”、“Value2”等,除非邏輯上的確需要編號。
5. 常量大寫
常量是某一類特殊的變量,它的特殊性就在于它不可修改。這種特殊性體現(xiàn)在命名上,就是我們通常用大寫字母表示變量名,如果常量名中有多個單詞,則用下劃線加以分割。例如:
const float PI = 3.14159; // 用const關(guān)鍵字定義一個float類型的常量PI const int MAX_LEN = 1024; // 用下劃線分割常量名6. 使用約定俗成的前綴
約定俗成的一些變量名前綴,可以很好地解釋變量的某些屬性,讓變量的含義一目了然。例如:變量加前綴s_,表示靜態(tài)(static)變量;變量加前綴g_,表示全局(global)變量;變量加前綴m_,表示成員(member)變量。
當(dāng)完成變量的定義后,系統(tǒng)會為這個變量分配內(nèi)存空間,進(jìn)而我們可以通過變量名對這塊內(nèi)存進(jìn)行讀寫訪問,將數(shù)據(jù)保存到內(nèi)存或者是從內(nèi)存讀取數(shù)據(jù)。但是,在真正使用變量之前,我們往往還需要對其進(jìn)行合理的初始化。這是因?yàn)樽兞慷x后,如果不進(jìn)行初始化,則系統(tǒng)會給定一個不確定的隨機(jī)值作為其初始值。而根據(jù)編譯器和目標(biāo)平臺的不同,這個隨機(jī)值則可能有所不同。這樣就可能導(dǎo)致同一程序在不同平臺上行為的不一致,帶來移植問題。同時,如果不小心使用了這個隨機(jī)值進(jìn)行操作,則可能導(dǎo)致程序運(yùn)行結(jié)果出錯,甚至程序崩潰,那就是一場災(zāi)難了。而變量初始化會給變量一個合理的初始值,可以很好地避免上面的這些問題。所以,在學(xué)習(xí)C++的一開始,就應(yīng)該養(yǎng)成“在定義變量的同時進(jìn)行初始化”的好習(xí)慣。
那么,我們該如何進(jìn)行變量的初始化呢?
第一種方式,可以在定義變量的同時,使用“=”賦值符將合適的初始值賦值給這個變量。例如:
// 定義一個int類型的變量nHeight,并利用“=”將其值初始化為175 int nHeight = 175;第二種方式,就是在定義變量時在變量名之后用“()”給出初始值,系統(tǒng)會用這個初始值完成變量的創(chuàng)建,從而完成初始化工作。例如:
// 通過“()”將其值初始化為175 int nHeight(175);除了以上兩種方式之外,在 C++11標(biāo)準(zhǔn)中,我們還可以利用一對大括號“{}”表示的初始化列表(initializer list)在定義變量時完成變量的初始化工作。例如:
//通過初始化列表將其值初始化為175 int nHeight{175};最佳實(shí)踐:為什么要使用初始化列表?
到這里,大家很自然地會提出這樣一個問題:C++中已經(jīng)有“=”和“()”可以完成變量的初始化了,為什么還要使用初始化列表來進(jìn)行變量的初始化?
初始化列表是C++11標(biāo)準(zhǔn)新引入的一個特性,除了統(tǒng)一變量初始化的形式之外,它還帶來另外一個好處:它可以預(yù)防變量初始化時的數(shù)據(jù)類型截?cái)?#xff0c;防止數(shù)據(jù)精度丟失。所謂的數(shù)據(jù)類型截?cái)?#xff0c;簡而言之,就是在使用某種精度較高的數(shù)據(jù)類型(例如,double)的數(shù)據(jù)對另一種精度較低的數(shù)據(jù)類型(例如,int)的變量進(jìn)行賦值時,C++會進(jìn)行隱式的類型截?cái)嘁詽M足類型轉(zhuǎn)換的需要。例如:
int x = 7.3; // 一個double類型的數(shù)據(jù)7.3被截?cái)喑蒳nt類型的數(shù)據(jù)7在編譯上面的代碼時,雖然在這個過程中丟失了0.3這個數(shù)據(jù),但編譯器不會給出任何錯誤或者警告信息。但是,在C++11中,如果使用初始化列表“{}”來進(jìn)行初始化,編譯器則會對這種數(shù)據(jù)類型截?cái)喟l(fā)出警告,提示用戶數(shù)據(jù)精度的丟失。例如:
// 警告:用double類型的數(shù)據(jù)初始化int類型的變量會產(chǎn)生類型截?cái)?#xff0c;丟失數(shù)據(jù)精度 int x1 = {7.3}; // 正確:雖然7是一個int類型的數(shù)據(jù),但是可以使用char類型精確地表達(dá), // 因而不會導(dǎo)致數(shù)據(jù)類型截?cái)喽鴣G失精度錯誤 char x2{7};在C++中,如果一個初始值可以被精確地表達(dá)為目標(biāo)類型,那么就不存在數(shù)據(jù)類型截?cái)唷5堊⒁?#xff0c;double類型至int類型的轉(zhuǎn)換通常都會被認(rèn)為是數(shù)據(jù)類型截?cái)?#xff0c;會產(chǎn)生精度的丟失,即使是從7.0轉(zhuǎn)換至7。初始化列表對于類型轉(zhuǎn)換的處理增強(qiáng)了C++靜態(tài)類型系統(tǒng)的安全性。傳統(tǒng)的依賴于編程人員的初始化類型安全檢查,在 C++11中,通過初始化列表由編譯器實(shí)施,這樣會減輕編程人員的負(fù)擔(dān),也更加安全。所以,如果可以,應(yīng)該盡可能地使用初始化列表來完成變量的初始化。
這里需要特別指出的是,我們不能使用初始化列表對auto 類型(一種特殊的數(shù)據(jù)類型,它相當(dāng)于一種數(shù)據(jù)類型的占位符。用它作為數(shù)據(jù)類型定義變量時,它并不具體地指定變量的數(shù)據(jù)類型,變量的真實(shí)數(shù)據(jù)類型將在編譯時根據(jù)其初始值自動推斷而得。在稍后的3.5.2小節(jié)中,我們將詳細(xì)加以介紹)的變量進(jìn)行初始化。如果那樣的話,這個變量的類型會被編譯器檢測為初始化列表類型,而不是初始化列表中真正的初始值的類型。?
知道更多:用戶自定義數(shù)據(jù)標(biāo)識(User-defined literals)創(chuàng)建特殊數(shù)據(jù)
在表示數(shù)據(jù)的時候,C++提供了許多內(nèi)建的數(shù)據(jù)類型的數(shù)據(jù)標(biāo)識供我們使用,這樣我們在表達(dá)數(shù)據(jù)的時候,加上相應(yīng)的數(shù)據(jù)標(biāo)識,將使得我們要表達(dá)的數(shù)據(jù)更加準(zhǔn)確而直觀。例如:
1.2 // 默認(rèn)double雙精度浮點(diǎn)型 1.2F // F指定float單精度浮點(diǎn)型 19821003ULL // ULL表示unsigned long long 64位無符號長整型除了這些內(nèi)建的數(shù)據(jù)標(biāo)識之外,C++11還通過在變量后面加上一個用戶自定義的后綴來標(biāo)定所需的數(shù)據(jù)類型以支持“用戶自定義數(shù)據(jù)標(biāo)識”,例如:
// 定義表示英寸的數(shù)據(jù)標(biāo)識inch constexpr double operator"" _inch(const long double in) { return in*0.0254; // 將英寸單位換算成米單位 }在這里,我們實(shí)際上定義了一個操作符(必須以“_”開始),它以操作符之前的數(shù)據(jù)為參數(shù),參數(shù)類型就是相應(yīng)的數(shù)據(jù)取值范圍最大的類型。例如,表示整型數(shù)的是unsigned long long、表示浮點(diǎn)數(shù)的是long double。當(dāng)然,也可以將整個數(shù)據(jù)作為一個字符串,以const char*的參數(shù)形式傳入。傳入的參數(shù)在經(jīng)過一定的處理后,返回的就是這個數(shù)據(jù)加上數(shù)據(jù)標(biāo)識后表示的真實(shí)數(shù)據(jù)。這樣,我們就可以直接在程序中使用“_inch”這個用戶自定義的數(shù)據(jù)標(biāo)識,直接定義以英寸為單位的數(shù)據(jù)。例如:
// 定義一臺電視機(jī)的尺寸為54英寸, // 然后換算成以米為單位的數(shù)據(jù)賦值給變量tvsize double tvsize = 54.0_inch; cout<<"54 inch = "<<tvsize<<" m"<<endl;在上面這段代碼中,我們使用“_inch”數(shù)據(jù)標(biāo)識直接定義了電視機(jī)的尺寸。當(dāng)編譯器在編譯這段代碼時,首先會分析為變量賦值數(shù)據(jù)的后綴,然后將后綴之前的數(shù)據(jù)作為參數(shù),調(diào)用定義數(shù)據(jù)標(biāo)識的函數(shù),并將函數(shù)的返回值作為這個數(shù)據(jù)的真實(shí)數(shù)值。用戶自定義數(shù)據(jù)標(biāo)識機(jī)制只是簡簡單單的允許用戶制定一個新的后綴,并決定如何對它之前的數(shù)據(jù)進(jìn)行處理。在其中,我們可以進(jìn)行單位的換算,例如將英寸換算成米,也可以將其構(gòu)造成新的數(shù)據(jù)類型,例如將一個二進(jìn)制數(shù)構(gòu)造成十進(jìn)制數(shù)等等。
因?yàn)槲覀冊诙x數(shù)據(jù)標(biāo)識的時候使用了constexpr關(guān)鍵字,constexpr關(guān)鍵字的作用是實(shí)現(xiàn)在編譯時期進(jìn)行預(yù)處理計(jì)算,所以在編譯的時候,編譯器會直接將這個以英寸為單位的數(shù)據(jù)換算成以米為單位的數(shù)據(jù),并賦值給相應(yīng)的變量。
通過這樣的方式,我們可以直接在代碼中表示各種不同類型的數(shù)據(jù),例如英寸長度、角度、二進(jìn)制數(shù)等等,使得我們在使用不同類型的數(shù)據(jù)的時候?qū)⒏又庇^,也更加方便,更加人性化。
?
原文地址:http://www.cnblogs.com/nihaoCPP/p/3966286.html
轉(zhuǎn)載于:https://www.cnblogs.com/wodehao0808/p/4211025.html
總結(jié)
以上是生活随笔為你收集整理的(转载)你好,C++(7)第三部分 C++世界众生相 3.2.1 变量的定义与初始化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 怎么知道银行卡是一类还是二类卡
- 下一篇: 最懂中文的H5前端框架amazeUI