C++程序入門——表達(dá)式講解
在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ù)字開頭,只能包括大小寫英文字母、下劃線及數(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ù)的名字。
C++程序入門——表達(dá)式講解 前面提到關(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ù)字化的(詳情參見《C++從零開始(三)》中的類型一節(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)什么后綴都沒寫時(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ǔ)言,根本沒有提供字符串的必要性。不過(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ù)字之間建立映射。
現(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。
這里的問題就是為什么是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ù)提到(但不一定全部提到)。 **二元操作符有:** +-*/% 其前后各接一數(shù)字,返回兩數(shù)字之和、差、積、商、余數(shù)。
如:34+4.4f的返回值是38.4;3+-9.3f的返回值是-6.3。34-4的返回值是30;5-234的返回值是-229。3*2的返回值是6;10/3的返回值是3。10%3的返回值是1;20%7的返回值是6。
&&|| 其前后各接一邏輯值,返回兩邏輯值之“與”運(yùn)算邏輯值和“或”運(yùn)算邏輯值。
如:'A'&&34.3f的返回值是邏輯真,為1;34&&0的返回值是邏輯假,為0。
0||'B'的返回值是邏輯真,為 1;0||0的返回值是邏輯假,為0。
&|^ 其前后各接一數(shù)字,返回兩數(shù)字之“與”運(yùn)算、“或”運(yùn)算、“異或”運(yùn)算值。
如前面所說(shuō),先將兩側(cè)的數(shù)字轉(zhuǎn)成二進(jìn)制數(shù),然后對(duì)各位進(jìn)行與、或、異或操作。如:4&6的返回值是4,4轉(zhuǎn)為00000100,6轉(zhuǎn)為00000110各位相與得,00000100,為4。
4|6的返回值是6,4轉(zhuǎn)為00000100,6轉(zhuǎn)為00000110各位相或得,00000110,為6。
4^6的返回值是2,4轉(zhuǎn)為00000100,6轉(zhuǎn)為00000110各位相異或得,00000010,為2。 >=34的返回值是0,為邏輯假;32=23和23>=14的返回值都是1,為邏輯真;54>>與>2的返回值就是00000001,為1。 左移和右移有什么用?用于一些基于二進(jìn)制數(shù)的算法,不過(guò)還可以順便作為一個(gè)簡(jiǎn)單的優(yōu)化手段??紤]十進(jìn)制數(shù)3524,我們將它左移2位,變成352400,比原數(shù)擴(kuò)大了100倍,準(zhǔn)確的說(shuō)應(yīng)該是擴(kuò)大了10的2次方倍。如果將3524右移2位,變成35,相當(dāng)于原數(shù)除以100的商。
同樣,前面4>>2,等效于4/4的商;32>>3相當(dāng)于32/8,即相當(dāng)于32除以2的3次方的商。而4?:。它的返回值為:如果是邏輯真,返回,否則返回。如: 34?4:2的返回值就是4,因?yàn)?4非零,為邏輯真,返回4。而0?4:2的返回值就是2,因?yàn)?為邏輯假,返回2。 **表達(dá)式** 你應(yīng)該發(fā)現(xiàn)前面的荒謬之處了——12>435返回值為0,那為什么不直接寫0還吃飽了撐了寫個(gè)12>435在那?這就是表達(dá)式的意義了。 前面說(shuō)“>”的前后各接一數(shù)字,但是操作符是操作數(shù)字并返回?cái)?shù)字的符號(hào),因?yàn)樗祷財(cái)?shù)字,因此可以放在上面說(shuō)的任何一個(gè)要求接數(shù)字的地方,也就形成了所謂的表達(dá)式。
如:23*54/45>34的返回值就是0,因?yàn)?3*54的返回值為1242;然后又將1242作為“/”的左接數(shù)字,得到新的返回值27.6;最后將27.6作為“>”的左接數(shù)字進(jìn)而得到返回值0,為邏輯假。 因此表達(dá)式就是由一系列返回?cái)?shù)字的東西和操作符組合而成的一段代碼,其由于是由操作符組成的,故一定返回值。而前面說(shuō)的“返回?cái)?shù)字的東西”則可以是另一個(gè)表達(dá)式,或者一個(gè)變量,或者一個(gè)具有返回值的函數(shù),或者具有數(shù)字類型操作符重載的類的對(duì)象等,反正只要是能返回一個(gè)數(shù)字的東西。如果對(duì)于何謂變量、函數(shù)、類等這些名詞感到陌生,不需要去管它們,在后繼的文章中將會(huì)一一說(shuō)明。 因此34也是一個(gè)表達(dá)式,其返回值為34,只不過(guò)是沒有操作符的表達(dá)式罷了(在后面將會(huì)了解到34其實(shí)是一種操作符)。故表達(dá)式的概念其實(shí)是很廣的,只要有返回值的東西就可以稱為表達(dá)式。 由于表達(dá)式里有很多操作符,執(zhí)行操作符的順序依賴于操作符的優(yōu)先級(jí),就和數(shù)學(xué)中的一樣,*、/的優(yōu)先級(jí)大于+、-,而+、-又大于>、<等邏輯操作符。不用去刻意記住操作符的優(yōu)先級(jí),當(dāng)不能確定操作符的執(zhí)行順序時(shí),可以使用小括號(hào)來(lái)進(jìn)行指定。
如: ((1+2)*3)+3)/4的返回值為3,而1+2*3+3/4的返回值為7。注意3/4為0,因?yàn)?/4的商是0。當(dāng)希望進(jìn)行浮點(diǎn)數(shù)除法或乘法時(shí),只需讓操作數(shù)中的某一個(gè)為浮點(diǎn)數(shù)即可,如:3/4.0的返回值為0.75。
& | ^ ~等的應(yīng)用 前面提過(guò)邏輯操作符“&&”、“||”、“!”等,作為表示邏輯,其被C++提供一點(diǎn)都不值得驚奇。但是為什么要有一個(gè)將數(shù)字轉(zhuǎn)成二進(jìn)制數(shù),然后對(duì)二進(jìn)制數(shù)的各位進(jìn)行邏輯操作的這么一類操作符呢?首先是CPU提供了相應(yīng)的指令,并且其還有著下面這個(gè)非常有意義的應(yīng)用。 考慮一十字路口,每個(gè)路口有三盞紅綠燈,分別指明能否左轉(zhuǎn)、右轉(zhuǎn)及直行。
共有12盞,現(xiàn)在要為它編寫一個(gè)控制程序,不管這程序的功能怎樣,首先需要將紅綠燈的狀態(tài)轉(zhuǎn)化為數(shù)字,因?yàn)殡娔X只知道數(shù)字。所以用3個(gè)數(shù)字分別表示某路口的三盞紅綠燈,因此每個(gè)紅綠燈的狀態(tài)由一個(gè)數(shù)字來(lái)表示,假設(shè)紅燈為0,綠燈為1(不考慮黃燈或其他情況)。
后來(lái)忽然發(fā)現(xiàn),其實(shí)也可以用一個(gè)數(shù)字表示一個(gè)路口的三盞紅綠燈狀態(tài),如用110表示左轉(zhuǎn)綠燈、直行綠燈而右轉(zhuǎn)紅燈。上面的110是一個(gè)十進(jìn)制數(shù)字,它的每一位實(shí)際都可以為0~9十個(gè)數(shù)字,但是這里只應(yīng)用到了兩個(gè):0和1,感覺很浪費(fèi)。
故選擇二進(jìn)制數(shù)來(lái)表示,還是110,但是是二進(jìn)制數(shù)了,轉(zhuǎn)成十進(jìn)制數(shù)為6,即使當(dāng)為111時(shí)轉(zhuǎn)成十進(jìn)制數(shù)也只是7,比前面的110這個(gè)十進(jìn)制數(shù)小多了,節(jié)約了……??什么?? 我們?cè)诩埳蠈憯?shù)字235425234一定比寫134這個(gè)數(shù)字要更多地占用紙張(假設(shè)字都一樣大)。因此記錄一個(gè)大的數(shù)比記錄一個(gè)小的數(shù)要花費(fèi)更多的資源。
簡(jiǎn)直荒謬!不管是100還是1000,都只是一個(gè)數(shù)字,為什么記錄大的數(shù)字就更費(fèi)資源?因?yàn)殡娔X并不是數(shù)字計(jì)算機(jī),而是電子計(jì)算機(jī),它是基于狀態(tài)而不是基于數(shù)字的,這在下篇會(huì)詳細(xì)說(shuō)明。
電腦必須使用某種表示方式來(lái)代表一個(gè)數(shù)字,而那個(gè)表示方式和二進(jìn)制很像,但并不是二進(jìn)制數(shù),故出現(xiàn)記錄大的數(shù)較小的數(shù)更耗資源,這也就是為什么上面整型數(shù)要分什么長(zhǎng)整型短整型的原因了。 下面繼續(xù)上面的思考。使用了110這個(gè)二進(jìn)制數(shù)來(lái)表示三盞紅綠燈的狀態(tài),那么現(xiàn)在要知道110這個(gè)數(shù)字代表左轉(zhuǎn)紅綠燈的什么狀態(tài)。以數(shù)字的第三位表示左轉(zhuǎn),不過(guò)電腦并不知道這個(gè),因此如下:110&100。
這個(gè)表達(dá)式的返回值是100,非零,邏輯真。假設(shè)某路口的狀態(tài)為010,則同樣的010&100,返回值為0,邏輯假。因此使用“&”操作符可以將二進(jìn)制數(shù)中的某一位或幾位的狀態(tài)提取出來(lái)。
所以我們要了解一個(gè)數(shù)字代表 的紅綠燈狀態(tài)中的左轉(zhuǎn)紅綠燈是否綠燈時(shí),只需讓它和100相與即可。 現(xiàn)在要保持其他紅綠燈的狀態(tài)不變,僅僅使左轉(zhuǎn)紅綠燈為綠燈,如當(dāng)前狀態(tài)為010,為了使左轉(zhuǎn)紅綠燈為綠燈,值應(yīng)該為110,這可以通過(guò)010|100做到。
如果當(dāng)前狀態(tài)是001,則001|100為101,正確——直行和右轉(zhuǎn)的紅綠燈狀態(tài)均沒有發(fā)生變化。因此使用“|”操作符可以給一個(gè)二進(jìn)制數(shù)中的某一位或幾位設(shè)置狀態(tài),但只能設(shè)置為1,如果想設(shè)置為0,如101,要關(guān)掉左轉(zhuǎn)的綠燈,則101&~100,返回值為001。
上面一直提到的路口紅綠燈的狀態(tài)實(shí)際編寫時(shí)可以使用一個(gè)變量來(lái)表示,而上面的100也可以用一個(gè)標(biāo)識(shí)符來(lái)表示,如state&TS_LEFT,就可以表示檢查變量state所表示的狀態(tài)中的左轉(zhuǎn)紅綠燈的狀態(tài)。 上面的這種方法被大量地運(yùn)用,如創(chuàng)建一個(gè)窗口,一個(gè)窗口可能有二三十個(gè)風(fēng)格,則通過(guò)上面的方法,就可以只用一個(gè)32位長(zhǎng)的二進(jìn)制數(shù)字就表示了窗口的風(fēng)格,而不用去弄二三十個(gè)數(shù)字來(lái)分別代表每種風(fēng)格是否具有。
聲明:免責(zé)聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻(xiàn)自行上傳,本網(wǎng)站不擁有所有權(quán),也不承認(rèn)相關(guān)法律責(zé)任。如果您發(fā)現(xiàn)本社區(qū)中有涉嫌抄襲的內(nèi)容,請(qǐng)發(fā)
送郵件至:operations@xinnet.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),本站將立刻刪除涉嫌侵權(quán)內(nèi)容。本站原創(chuàng)內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)
需注明出處:新網(wǎng)idc知識(shí)百科