C++程序設(shè)計(jì)從零開(kāi)始之表達(dá)式

字號(hào):

在學(xué)英語(yǔ)時(shí),第一時(shí)間學(xué)的是字母,其是英語(yǔ)的基礎(chǔ)。同樣,在C++中,所有的代碼都是通過(guò)標(biāo)識(shí)符(Identifier)、表達(dá)式(Expression)和語(yǔ)句(Statement)及一些必要的符號(hào)(如大括號(hào)等)組成,在此先說(shuō)明何謂標(biāo)識(shí)符。
    標(biāo)識(shí)符
    標(biāo)識(shí)符是一個(gè)字母序列,由大小寫英文字母、下劃線及數(shù)字組成,用于標(biāo)識(shí)。標(biāo)識(shí)就是標(biāo)出并識(shí)別,也就是名字。其可以作為后面將提到的變量或者函數(shù)或者類等的名字,也就是說(shuō)用來(lái)標(biāo)識(shí)某個(gè)特定的變量或者函數(shù)或者類等C++中的元素。
    比如:abc就是一個(gè)合法的標(biāo)識(shí)符,即abc可以作為變量、函數(shù)等元素的名字,但并不代表abc就是某個(gè)變量或函數(shù)的名字,而所謂的合法就是任何一個(gè)標(biāo)識(shí)符都必須不能以數(shù)字開(kāi)頭,只能包括大小寫英文字母、下劃線及數(shù)字,不能有其它符號(hào),如,!^等,并且不能與C++關(guān)鍵字相同。也就是我們?cè)诮o一個(gè)變量或函數(shù)起名字的時(shí)候,必須將起的名字看作是一個(gè)標(biāo)識(shí)符,并進(jìn)而必須滿足上面提出的要求。如12ab_C就不是一個(gè)合法的標(biāo)識(shí)符,因此我們不能給某個(gè)變量或函數(shù)起12ab_C這樣的名字;ab_12C就是合法的標(biāo)識(shí)符,因此可以被用作變量或函數(shù)的名字。
    前面提到關(guān)鍵字,在后續(xù)的語(yǔ)句及一些聲明修飾符的介紹中將發(fā)現(xiàn),C++提供了一些特殊的標(biāo)識(shí)符作為語(yǔ)句的名字,用以標(biāo)識(shí)某一特定語(yǔ)句,如if、while等;或者提供一些修飾符用以修飾變量、函數(shù)等元素以實(shí)現(xiàn)語(yǔ)義或給編譯器及連接器提供一些特定信息以進(jìn)行優(yōu)化、查錯(cuò)等操作,如extern、static等。因此在命名變量或函數(shù)或其他元素時(shí),不能使用if、extern等這種C++關(guān)鍵字作為名字,否則將導(dǎo)致編譯器無(wú)法確認(rèn)是一個(gè)變量(或函數(shù)或其它C++元素)還是一條語(yǔ)句,進(jìn)而無(wú)法編譯。
    如果要讓某個(gè)標(biāo)識(shí)符是特定變量或函數(shù)或類的名字,就需要使用聲明,在后續(xù)的文章中再具體說(shuō)明。
    數(shù)字
    C++作為電腦編程語(yǔ)言,電腦是處理數(shù)字的,因此C++中的基礎(chǔ)東西就是數(shù)字。C++中提供兩種數(shù)字:整型數(shù)和浮點(diǎn)數(shù),也就是整數(shù)和小數(shù)。但由于電腦實(shí)際并不是想象中的數(shù)字化的(詳情參見(jiàn)《C++從零開(kāi)始(三)》中的類型一節(jié)),所以整型數(shù)又分成了有符號(hào)和無(wú)符號(hào)整型數(shù),而浮點(diǎn)數(shù)則由精度的區(qū)別而分成單精度和雙精度浮點(diǎn)數(shù),同樣的整型數(shù)也根據(jù)長(zhǎng)度分成長(zhǎng)整型和短整型。
    要在C++代碼中表示一個(gè)數(shù)字,直接書寫數(shù)字即可,如:123、34.23、-34.34等。由于電腦并非以數(shù)字為基礎(chǔ)而導(dǎo)致了前面數(shù)字的分類,為了在代碼中表現(xiàn)出來(lái),C++提供了一系列的后綴進(jìn)行表示,如下:
    u或U 表示數(shù)字是無(wú)符號(hào)整型數(shù),如:123u,但并不說(shuō)明是長(zhǎng)整型還是短整型
    l或L 表示數(shù)字是長(zhǎng)整型數(shù),如:123l;而123ul就是無(wú)符號(hào)長(zhǎng)整型數(shù);而34.4l就是長(zhǎng)雙精度浮點(diǎn)數(shù),等效于雙精度浮點(diǎn)數(shù)
    i64或I64 表示數(shù)字是長(zhǎng)長(zhǎng)整型數(shù),其是為64位操作系統(tǒng)定義的,長(zhǎng)度比長(zhǎng)整型數(shù)長(zhǎng)。如:43i64   f或F 表示數(shù)字是單精度浮點(diǎn)數(shù),如:12.3f   e或E 表示數(shù)字的次冪,如:34.4e-2就是0.344;0.2544e3f表示一個(gè)單精度浮點(diǎn)數(shù),值為254.4
    當(dāng)什么后綴都沒(méi)寫時(shí),則根據(jù)有無(wú)小數(shù)點(diǎn)及位數(shù)來(lái)決定其具體類型,如:123表示的是有符號(hào)整型數(shù),而12341434則是有符號(hào)長(zhǎng)整型數(shù);而34.43表示雙精度浮點(diǎn)數(shù)。
    為什么要搞這么多事出來(lái),還分什么有符號(hào)無(wú)符號(hào)之類的?這全是因?yàn)殡娔X并非基于數(shù)字的,而是基于狀態(tài)的,詳情在下篇中將詳細(xì)說(shuō)明。
    作為科學(xué)計(jì)算,可能經(jīng)常會(huì)碰到使用非十進(jìn)制數(shù)字,如16進(jìn)制、8進(jìn)制等,C++也為此提供了一些前綴以進(jìn)行支持。
    在數(shù)字前面加上0x或0X表示這個(gè)數(shù)字是16進(jìn)制表示的,如:0xF3Fa、0x11cF。而在前面加一個(gè)0則表示這個(gè)數(shù)字是用8進(jìn)制表示的,如:0347,變?yōu)槭M(jìn)制數(shù)就為231。但16進(jìn)制和8進(jìn)制都不能用于表示浮點(diǎn)數(shù),只能表示整型數(shù),即0x34.343是錯(cuò)誤的。
    字符串
    C++除了提供數(shù)字這種最基礎(chǔ)的表示方式外,還提供了字符及字符串。這完全只是出于方便編寫程序而提供的,C++作為電腦語(yǔ)言,根本沒(méi)有提供字符串的必要性。不過(guò)由于人對(duì)電腦的基本要求就是顯示結(jié)果,而字符和字符串都由于是人易讀的符號(hào)而被用于顯示結(jié)果,所以C++專門提供了對(duì)字符串的支持。
    前面說(shuō)過(guò),電腦只認(rèn)識(shí)數(shù)字,而字符就是文字符號(hào),是一種圖形符號(hào)。為了使電腦能夠處理符號(hào),必須通過(guò)某種方式將符號(hào)變成數(shù)字,在電腦中這通過(guò)在符號(hào)和數(shù)字之間建立一個(gè)映射來(lái)實(shí)現(xiàn),也就是一個(gè)表格。表格有兩列,一列就是我們欲顯示的圖形符號(hào),而另一列就是一個(gè)數(shù)字,通過(guò)這么一張表就可以在圖形符號(hào)和數(shù)字之間建立映射?,F(xiàn)在已經(jīng)定義出一標(biāo)準(zhǔn)表,稱為ASCII碼表,幾乎所有的電腦硬件都支持這個(gè)轉(zhuǎn)換表以將數(shù)字變成符號(hào)進(jìn)而顯示計(jì)算結(jié)果。
    有了上面的表,當(dāng)想說(shuō)明結(jié)果為“A”時(shí),就查ASCII碼表,得到“A”這個(gè)圖形符號(hào)對(duì)應(yīng)的數(shù)字是65,然后就告訴電腦輸出序號(hào)為65的字符,最后屏幕上顯示“A”。
    這明顯地繁雜得異常,為此C++就提供了字符和字符串。當(dāng)我們想得到某一個(gè)圖形符號(hào)的ASCII碼表的序號(hào)時(shí),只需通過(guò)單引號(hào)將那個(gè)字符括起來(lái)即可,如:’A’,其效果和65是一樣的。當(dāng)要使用不止一個(gè)字符時(shí),則用雙引號(hào)將多個(gè)字符括起來(lái),也就是所謂的字符串了,如:"ABC"。因此字符串就是多個(gè)字符連起來(lái)而已。但根據(jù)前面的說(shuō)明易發(fā)現(xiàn),字符串也需要映射成數(shù)字,但它的映射就不像字符那么簡(jiǎn)單可以通過(guò)查表就搞定的,對(duì)于此,將在后續(xù)文章中對(duì)數(shù)組作過(guò)介紹后再說(shuō)明。
    操作符
    電腦的基本是數(shù)字,那么電腦的所有操作都是改變數(shù)字,因此很正常地C++提供了操作數(shù)字的一些基本操作,稱作操作符(Operator),如:+ - * / 等。任何操作符都要返回一個(gè)數(shù)字,稱為操作符的返回值,因此操作符就是操作數(shù)字并返回?cái)?shù)字的符號(hào)。作為一般性地分類,按操作符同時(shí)作用的數(shù)字個(gè)數(shù)分為一元、二元和三元操作符。
    一元操作符有: +   其后接數(shù)字,原封不動(dòng)地返回后接的數(shù)字。如: +4.4f的返回值是4.4;+-9.3f的返回值是-9.3。完全是出于語(yǔ)義的需要,如表示此數(shù)為正數(shù)。 -   其后接數(shù)字,將后接的數(shù)字的符號(hào)取反。如: -34.4f的返回值是-34.4;-(-54)的返回值是54。用于表示負(fù)數(shù)。 !   其后接數(shù)字,邏輯取反后接的數(shù)字。邏輯值就是“真”或“假”,為了用數(shù)字表示邏輯值,在 C++中規(guī)定,非零值即為邏輯真,而零則為邏輯假。因此3、43.4、’A’都表示邏輯真,而0則表示邏輯假。邏輯值被應(yīng)用于后續(xù)的判斷及循環(huán)語(yǔ)句中。而邏輯取反就是先判斷“!”后面接的數(shù)字是邏輯真還是邏輯假,然后再將相應(yīng)值取反。如:
    !5的返回值是0,因?yàn)橄扔?非零而知是邏輯真,然后取反得邏輯假,故最后返回0。
    !!345.4的返回值是1,先因345.4非零得邏輯真,取反后得邏輯假,再取反得邏輯真。雖然只要非零就是邏輯真,但作為編譯器返回的邏輯真,其一律使用1來(lái)代表邏輯真。 ~
    其后接數(shù)字,取反后接的數(shù)字。取反是邏輯中定義的操作,不能應(yīng)用于數(shù)字。為了對(duì)數(shù)字應(yīng)用取反操作,電腦中將數(shù)字用二進(jìn)制表示,然后對(duì)數(shù)字的每一位進(jìn)行取反操作(因?yàn)槎M(jìn)制數(shù)的每一位都只能為1或0,正好符合邏輯的真和假)。如~123的返回值就為-124。先將123轉(zhuǎn)成二進(jìn)制數(shù)01111011,然后各位取反得10000100,最后得-124。
    這里的問(wèn)題就是為什么是8位而不是16位二進(jìn)制數(shù)。因?yàn)?23小于128,被定位為char類型,故為8位(關(guān)于char是什么將下篇介紹)。如果是~123ul,則返回值為4294967172。
    為什么要有數(shù)字取反這個(gè)操作?因?yàn)镃PU提供了這樣的指令。并且其還有著很不錯(cuò)且很重要的應(yīng)用,后面將介紹。     關(guān)于其他的一元操作符將在后續(xù)文章中陸續(xù)提到(但不一定全部提到)。