《程序設(shè)計(jì)與C語(yǔ)言》課件第3章_第1頁(yè)
《程序設(shè)計(jì)與C語(yǔ)言》課件第3章_第2頁(yè)
《程序設(shè)計(jì)與C語(yǔ)言》課件第3章_第3頁(yè)
《程序設(shè)計(jì)與C語(yǔ)言》課件第3章_第4頁(yè)
《程序設(shè)計(jì)與C語(yǔ)言》課件第3章_第5頁(yè)
已閱讀5頁(yè),還剩138頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第3章C語(yǔ)言基本知識(shí)3.1C語(yǔ)言基本元素3.2C的基本數(shù)據(jù)類(lèi)型

3.3C的運(yùn)算符及表達(dá)式

習(xí)題3

3.1C語(yǔ)言基本元素3.1.1C的字符集

C語(yǔ)言中可用的字符有以下幾類(lèi):

(1)大小寫(xiě)的英文字母:A,B,…,Z,a,b,…,z。

(2)阿拉伯?dāng)?shù)字:0,1,2,3,4,5,6,7,8,9。

(3)特殊字符:+,-,*,/,%,=,-,(,),&,#,!,|,<,>,·,,,;,:,″,′,?,{,},~,\,[,],^,共29個(gè)。

(4)不可打印的字符:空格,換行符,制表符。3.1.2標(biāo)識(shí)符標(biāo)識(shí)符是某種對(duì)象的名字或標(biāo)記,這些對(duì)象可以是變量名、函數(shù)名、標(biāo)號(hào)等。標(biāo)識(shí)符的構(gòu)成成分是:字母、數(shù)字和下劃線;構(gòu)成規(guī)則是:以字母或下劃線開(kāi)頭的字符序列。對(duì)象的取名最好能直觀表達(dá)該對(duì)象的意義,這樣能很自然地引起聯(lián)想,便于閱讀和理解。比如表示圓周率可取名pi,表示求和可取名sum等。在C語(yǔ)言中,大寫(xiě)、小寫(xiě)字母表示不同的意義,這樣sum和SUM就是兩個(gè)不同的名字,甚至sum和sUm也不相同。正確的標(biāo)識(shí)符:abc,_ab2,_123,total等。不正確的標(biāo)識(shí)符:123,abc,ab*c等。3.1.3關(guān)鍵字

C語(yǔ)言中有一種特殊的標(biāo)識(shí)符,它們?cè)诔绦蛑杏刑囟ǖ暮x,用在特定的地方,不能隨便移作它用。這些標(biāo)識(shí)符是C語(yǔ)言本身帶來(lái)的,用戶在定義對(duì)象名時(shí)不能使用它們。這樣的標(biāo)識(shí)符稱(chēng)為關(guān)鍵字或保留字,它們都是一些英文單詞或縮寫(xiě)。C語(yǔ)言的關(guān)鍵字如下:autobreakcasecharconstcontinuedefaultdodoubleelseenumexternfloatforgotoifintlongregisterreturnshortsignedsizeofstaticstructswitchtypedefunionunsignedvoidvolatilewhile共有32個(gè),不需要死記,當(dāng)學(xué)習(xí)過(guò)它們?nèi)绾问褂煤?,自然就?huì)熟悉起來(lái)。而在以后的學(xué)習(xí)中,就要注意它們都用在什么地方,起什么作用,如何使用它們來(lái)構(gòu)成程序。3.1.4變量和常量

1.常量常量是其值在程序執(zhí)行過(guò)程中不變的量,如123,45.2,′a′,″abc″等,這樣的常量也稱(chēng)為常量直接量,因?yàn)槠浜x是由其字面意義直接表達(dá)的。還有一種常量稱(chēng)為符號(hào)常量,是用一個(gè)名字來(lái)代表常量。定義符號(hào)常量的方法是用define命令把一個(gè)常量名和常量聯(lián)系起來(lái)。如 #defineNULL0就定義了一個(gè)常量名NULL,它代表0,以后在程序中遇到NULL,就用0來(lái)代替。符號(hào)常量一般用大寫(xiě)字母表示,以區(qū)別于變量。當(dāng)然也不一定非要大寫(xiě),也可以用小寫(xiě)字母表示。

2.變量變量是其值在程序執(zhí)行過(guò)程中可以改變的量。如定義sum是個(gè)變量,則執(zhí)行語(yǔ)句

sum=0;后,它的值為0,再執(zhí)行語(yǔ)句

sum=1;之后,它的值就變?yōu)?。之所以會(huì)有這些變化,是因?yàn)樽兞繉?shí)際上是內(nèi)存中的一段存儲(chǔ)單元,里面可以存放變化的數(shù)據(jù)。要想把內(nèi)存中的某段存儲(chǔ)單元和一個(gè)變量名聯(lián)系起來(lái),必須首先對(duì)變量進(jìn)行定義或聲明。變量聲明的一般形式是:

〈變量類(lèi)型〉〈變量列表〉;其中,〈變量類(lèi)型〉是C語(yǔ)言中可以使用的數(shù)據(jù)類(lèi)型;〈變量列表〉則由一個(gè)或多個(gè)用逗號(hào)分開(kāi)的標(biāo)識(shí)符(即變量名)組成,最后以分號(hào)結(jié)束。如語(yǔ)句

intsum,i;就定義了兩個(gè)變量sum和i,它們的類(lèi)型是整型。這樣就在內(nèi)存中開(kāi)辟出了兩個(gè)能存放整數(shù)的存儲(chǔ)單元。當(dāng)執(zhí)行語(yǔ)句

sum=0;i=1;之后,變量sum和i的存儲(chǔ)單元為:0sum1i如果再執(zhí)行語(yǔ)句

sum=i+2;則存儲(chǔ)單元變?yōu)椋簩?duì)i來(lái)說(shuō),是取出它的值1去和2相加,其存儲(chǔ)單元并未加以改變,這稱(chēng)為“非破壞性讀出”;而變量sum的存儲(chǔ)單元卻發(fā)生了改變,這稱(chēng)為“破壞性讀入”。當(dāng)把一個(gè)值放入一個(gè)存儲(chǔ)單元時(shí),都會(huì)覆蓋掉該單元中原有的內(nèi)容。3sum1i對(duì)變量必須先聲明后使用的原因在于:

(1)不同類(lèi)型的數(shù)據(jù)在編譯時(shí)分配的內(nèi)存空間大小不同,如字符型占一個(gè)字節(jié),整型占兩個(gè)字節(jié),而浮點(diǎn)型占四個(gè)字節(jié)。

(2)不同類(lèi)型的數(shù)據(jù)在內(nèi)存中的存儲(chǔ)形式不同,如字符型是以ASCII碼形式存儲(chǔ)的,整型是以補(bǔ)碼形式存儲(chǔ)的,浮點(diǎn)型是以指數(shù)形式存儲(chǔ)的。

(3)對(duì)不同類(lèi)型的數(shù)據(jù)所使用的運(yùn)算符不同,比如%(求余)運(yùn)算符只能用于整型變量而不能用于浮點(diǎn)型變量。因此變量在使用前必須先作類(lèi)型聲明。3.1.5字符串常量字符串常量在C程序中有著廣泛的使用,它是用雙引號(hào)括起來(lái)的字符序列,如:“string”、“thisisabook”、“sumis%d\n”等都是字符串常量。3.1.6注解為了更好地理解程序的功能,可在適當(dāng)?shù)牡胤郊幼⒔?。注解的?nèi)容放在“/*”和“*/”之間,編譯器把其中的內(nèi)容當(dāng)做空白符對(duì)待而不予處理。如:

/*thisisauserdefinedfunction*/就是對(duì)一個(gè)自定義函數(shù)的注解。一個(gè)注解可以寫(xiě)多行,只要注意“/*”和“*/”前后配對(duì)即可,如:

/*thisis

acomment */注意:注解不能嵌套。下面的寫(xiě)法

/*thisis/*acomment*/infunction*/就是錯(cuò)誤的。

【例3-1】注解的應(yīng)用。/*thisisasingleprogram*/#defineTEN10#include<stdio.h>main(){intsum;sum=2*TEN+2;/*namely:sum=2*10+2;*/printf(″sum=%d\n″,sum);return0;}該程序中用到了注解和符號(hào)常量。3.2C的基本數(shù)據(jù)類(lèi)型計(jì)算機(jī)可以處理多種多樣的數(shù)據(jù),這些數(shù)據(jù)有著內(nèi)在的聯(lián)系和差別。物以類(lèi)聚,計(jì)算機(jī)中的數(shù)據(jù)也如此,C語(yǔ)言把具有某些共同特征的數(shù)據(jù)歸為一類(lèi),以便處理。

C語(yǔ)言作為現(xiàn)代化的語(yǔ)言有著豐富的數(shù)據(jù)類(lèi)型,它既有基本類(lèi)型,又有構(gòu)造類(lèi)型,還有指針類(lèi)型和空類(lèi)型。圖3-1是C的數(shù)據(jù)類(lèi)型總覽。圖3-1C的數(shù)據(jù)類(lèi)型總覽3.2.1int(整數(shù))類(lèi)型

1.int類(lèi)型及其擴(kuò)展對(duì)不同的數(shù)據(jù)類(lèi)型,編譯系統(tǒng)會(huì)分配大小不同的內(nèi)存單元以存放某一類(lèi)數(shù)據(jù),因此就決定了每一類(lèi)數(shù)據(jù)必然有一定的取值范圍。整型數(shù)據(jù)是整數(shù)的一個(gè)子集。在ANSIC中,基本整型占兩個(gè)字節(jié),即16位二進(jìn)制位,最高位為符號(hào)位,數(shù)值位占15位,以補(bǔ)碼表示。這樣它的取值范圍在機(jī)器內(nèi)部是1000000000000000~0111111111111111,大小為-215~215-1,即-32768~32767?;菊偷臉?biāo)識(shí)符為int,由它可以定義整型變量,如

inti,j,k;則i、j、k這三個(gè)變量可以取-32768~32767之間的任何整數(shù)值。除了基本int類(lèi)型之外,C語(yǔ)言還提供了幾種int類(lèi)型的擴(kuò)充形式,即在類(lèi)型標(biāo)識(shí)符int之前添加修飾符而形成的新的整數(shù)類(lèi)型。這些修飾符為:short、long、unsigned。這樣可以擴(kuò)大整數(shù)類(lèi)型的取值范圍或更準(zhǔn)確地指明取值情況。

(1)shortint:短整型,可簡(jiǎn)寫(xiě)為short。其含義為其位數(shù)不比int類(lèi)型長(zhǎng),一般和int類(lèi)型一樣長(zhǎng),數(shù)值范圍也為-32768~32767,在表示較小的整數(shù)時(shí)使用。

(2)longint:長(zhǎng)整型,可簡(jiǎn)寫(xiě)為long。其含義為其位數(shù)不比int類(lèi)型短,其長(zhǎng)度規(guī)定為int類(lèi)型的兩倍,即4個(gè)字節(jié),取值范圍為-231~231-1,可表示更大的整數(shù)。我們可以用sizeof運(yùn)算符求出這兩種類(lèi)型的長(zhǎng)度。

【例3-2】求int、shortint和longint類(lèi)型的長(zhǎng)度。#include<stdio.h>main(){printf(″sizeof(int)=%d\n″,sizeof(int));printf(″sizeof(short)=%d\n″,sizeof(short));printf(″sizeof(long)=%d\n″,sizeof(long));return0;}程序中的sizeof是一個(gè)運(yùn)算符,不是函數(shù)名。這里是要計(jì)算數(shù)據(jù)類(lèi)型在內(nèi)存中所占的字節(jié)數(shù)。運(yùn)行輸出:sizeof(int)=2sizeof(short)=2sizeof(long)=4因此有如下關(guān)系:

sizeof(short)≤sizeof(int)≤sizeof(long)

(3)unsignedint:無(wú)符號(hào)整型,可簡(jiǎn)寫(xiě)為unsigned。其長(zhǎng)度和int類(lèi)型相同,但是它取消了符號(hào)位,把最高位也作為數(shù)值位使用,所以它的值全部是正的。它的取值范圍為0~65535。把int類(lèi)型中的0點(diǎn)拉到最左邊即為unsignedint類(lèi)型,所以其最大值即為int型中正、負(fù)最大絕對(duì)值之和,如圖3-2所示。圖3-2int類(lèi)型和unsignedint類(lèi)型的取值范圍

2.整型數(shù)據(jù)的溢出上述各種整數(shù)類(lèi)型都有各自的取值范圍,一旦越出了這個(gè)范圍,就不能正確地表示數(shù)據(jù),這種情況稱(chēng)為“溢出”。我們先來(lái)看兩個(gè)例子。

【例3-3】整型數(shù)據(jù)的溢出一。#include<stdio.h>main(){intmax,min;max=32767;min=max+1;printf(″max=%d,min=%d\n″,max,min);

return0;}運(yùn)行輸出:

max=32767,min=-32768為什么max加1以后會(huì)產(chǎn)生負(fù)值呢?這是因?yàn)檎麛?shù)在內(nèi)存中是以補(bǔ)碼形式存儲(chǔ)的,最高位是符號(hào)位,符號(hào)位為0時(shí)表示正數(shù),為1時(shí)表示負(fù)數(shù),而補(bǔ)碼運(yùn)算中的符號(hào)位是參與運(yùn)算的:

max:0111111111111111 + 1 min: 1000000000000000 ↑

符號(hào)位在max的最低位加1,由二進(jìn)制“逢二進(jìn)一”的進(jìn)位規(guī)則可得到min的形式,此時(shí)符號(hào)位變?yōu)?,表示該數(shù)已變成了負(fù)數(shù),而在補(bǔ)碼表示的情況下,min即為十進(jìn)制的-32768。

【例3-4】整型數(shù)據(jù)的溢出二。#include<stdio.h>main(){intmin,max;min=-32768;max=min-1;/*max=min+(-1);*/printf(″min=%d,max=%d\n″,min,max);return0;}運(yùn)行輸出: min=-32768,max=32767我們可以作同樣的分析,在補(bǔ)碼表示的情況下:

1000000000000000 -32768的補(bǔ)碼

+ 1111111111111111 -1的補(bǔ)碼

10111111111111111 32767因?yàn)檎椭挥?6位,所以最高位的進(jìn)位1被舍掉了,這樣最高位(符號(hào)位)變成了0,于是也就變成了正數(shù)。由以上兩例可以看出,在int類(lèi)型范圍內(nèi),正最大數(shù)加1即變?yōu)樨?fù)最小,負(fù)最小減1又變成了正最大。這印證了辯證法的一個(gè)樸素真理:自然界任何事物,其發(fā)展變化都有個(gè)限度,超過(guò)這個(gè)限度就會(huì)走向反面。從上面的討論中知道,用int類(lèi)型只能表示有限的整數(shù),如想表示更大范圍的數(shù),可選用其他類(lèi)型,如longint或float等。比如要正確進(jìn)行上例中的運(yùn)算,可把max和min全部定義成longint類(lèi)型。如果一個(gè)定義為longint類(lèi)型,而另一個(gè)仍為int類(lèi),則運(yùn)算結(jié)果仍然是不對(duì)的。

3.整型常量的幾種表示形式在C語(yǔ)言中,整型常量有三種表示形式:十進(jìn)制表示、八進(jìn)制表示和十六進(jìn)制表示。對(duì)于八進(jìn)制和十六進(jìn)制的整型常量,其特征還表現(xiàn)在數(shù)值的前綴上。

(1)十進(jìn)制表示:用十進(jìn)制數(shù)碼表示數(shù),不加前綴,如123、-45、0等。

(2)八進(jìn)制表示:用八進(jìn)制數(shù)碼表示數(shù),加前綴“0”(數(shù)字零),如0123、0275等,而0129則為錯(cuò)誤表示形式,因?yàn)?不是八進(jìn)制數(shù)碼。

(3)十六進(jìn)制表示:用十六進(jìn)制數(shù)碼表示數(shù),加前綴0x或0X(數(shù)字零和字母x(X)),如0x1A、0X8F等。除了前綴以外,整型常量還可以帶后綴,以明確指明該數(shù)屬于什么整數(shù)類(lèi)型。后綴可以是l(或L),u(或U)及其組合。l(或L)表示長(zhǎng)整型,u(或U)表示無(wú)符號(hào)整型,組合形式有:ul、uL、Ul、UL、lu、lU、Lu、LU。例如:0x12u表示無(wú)符號(hào)十六進(jìn)制,076UL表示無(wú)符號(hào)長(zhǎng)整型八進(jìn)制。整型常量加后綴主要用在函數(shù)調(diào)用中,當(dāng)函數(shù)的形參是某種類(lèi)型時(shí),若能提供相應(yīng)類(lèi)型的實(shí)參,則會(huì)更快地運(yùn)行。整型常量的類(lèi)型如何確定呢?實(shí)際上,如果一個(gè)整型常量的值在某一個(gè)整型類(lèi)型的取值范圍之內(nèi),那么它就可以屬于這種類(lèi)型。比如123,可以認(rèn)為它既是int型,又是unsignedint型,又是longint型,把它賦給這三種中任一類(lèi)型的變量都是正確的;再如65330,它就不是int類(lèi)型,但屬于unsignedint和longint類(lèi)型;而75887則肯定只能是longint類(lèi)型。不同類(lèi)型的整數(shù)之間可以進(jìn)行混合運(yùn)算,只要能保證結(jié)果不超越相應(yīng)類(lèi)型的取值范圍即可。

【例3-5】不同類(lèi)型整數(shù)之間的混合運(yùn)算。#include<stdio.h>main(){inti;unsignedintu;longintl;i=123;u=123;l=123;printf(″i=%d,u=%d,l=%d\n″,i,u,l);i=u+l;u=l+i;printf(″i=%d,u=%d\n″,i,u);return0;}運(yùn)行輸出:i=123,u=123,l=123i=246,u=3693.2.2char(字符)類(lèi)型字符類(lèi)型以char作為類(lèi)型標(biāo)識(shí)符。用char定義的變量稱(chēng)為字符變量,一個(gè)字符變量只能容納一個(gè)字符。一個(gè)字符常量是用單引號(hào)括起來(lái)的字符,如′a′、′A′、′*′等。在內(nèi)存中為一個(gè)字符變量分配一個(gè)字節(jié)的存儲(chǔ)空間。由于一個(gè)字節(jié)的8位二進(jìn)制位可以有28=256種不同的組合形式,因而可以有256個(gè)不同的字符。在這256個(gè)字符中,有些是可見(jiàn)的,有些是不可見(jiàn)的,不可見(jiàn)的字符只起控制作用,如換行、回車(chē)等。

1.字符在內(nèi)存中的存放形式字符在內(nèi)存中是以編碼的形式存放的。最常用的編碼方式是ASCII碼。存儲(chǔ)一個(gè)字符,實(shí)際上是把它的ASCII碼放入內(nèi)存中。例如:charc1,c2;c1=′a′;c2=′b′;則在內(nèi)存中:

c1:c2:因?yàn)椤鋋′的ASCII編碼是十進(jìn)制的97,二進(jìn)制的01100001;′b′的ASCII編碼是十進(jìn)制的98,二進(jìn)制的01100010。如以十進(jìn)制表示則為:c1:c2:01100001011000109798因?yàn)樽址趦?nèi)存中都是以二進(jìn)制形式表示的,所以字符型和整型之間有相通性,這些相通性表現(xiàn)在:

(1)字符型數(shù)據(jù)可以用整型形式輸出;反之,一定范圍內(nèi)的整數(shù)也可以用字符形式輸出。

(2)字符型變量和整型變量之間可以進(jìn)行混合運(yùn)算。

(3)整型變量可以接收字符常量,字符變量也可以接收整型數(shù)值,當(dāng)然這都要在一定范圍之內(nèi)。這一點(diǎn)可由以下例子說(shuō)明。

【例3-6】整型變量與字符型變量的輸出轉(zhuǎn)換。#include<stdio.h>main(){inti,j;charc1,c2;c1=′a′;c2=′b′;printf(″c1=%c,c1=%d;c2=%c,c2=%d\n″,c1,c1,c2,c2);i=97;j=98;printf(″i=%d,i=%c;j=%d,j=%c\n″,i,i,j,j);return0;}運(yùn)行輸出:c1=a,c1=97;c2=b,c2=98i=97,i=a;j=98,j=b英文大小寫(xiě)字母之間有這樣的關(guān)系:相應(yīng)小寫(xiě)字母的ASCII碼比大寫(xiě)字母大32。根據(jù)這一關(guān)系,我們可以將大小寫(xiě)字母任意轉(zhuǎn)換。

【例3-7】英文大、小寫(xiě)字母的轉(zhuǎn)換。#include<stdio.h>main(){charc1,c2;c1=′a′;c2=′B′;printf(″c1=%c,c2=%c\n″,c1,c2);c1=c1-32;c2=c2+32;printf(″c1=%c,c2=%c\n″,c1,c2);

return0;}運(yùn)行輸出:c1=a,c2=Bc1=A,c2=b

【例3-8】字符變量和整型變量互相接收對(duì)方類(lèi)型的數(shù)值。#include<stdio.h>main(){inti;charc;i=′a′;c=98;printf(″i=%d,c=%d\n″,i,c);printf(″i=%c,c=%c\n″,i,c);return0;}運(yùn)行輸出:i=97,c=98i=a,c=b一個(gè)字符在內(nèi)存中占一個(gè)字節(jié),對(duì)于這個(gè)字節(jié)的最高位,不同的系統(tǒng)有不同的處理方法。有的系統(tǒng)(如TurboC)就把最高位作符號(hào)位處理,因此一個(gè)字符的值就有正有負(fù)。編碼在0~127之間的字符以十進(jìn)制形式輸出時(shí)為正,而編碼在128~255之間的字符以十進(jìn)制形式輸出時(shí)為負(fù)。所以定義:

charch;就相當(dāng)于:

signedcharch;為了在以%d形式輸出字符時(shí)不出現(xiàn)負(fù)值,可以把字符定義成無(wú)符號(hào)字符:

unsignedcharch;對(duì)編碼在128~255之間的字符,不管是以char定義,還是以u(píng)nsignedchar類(lèi)型定義,它們?cè)谝宰址敵龈袷?c輸出時(shí)都是擴(kuò)展的ASCII碼表中的字符。

【例3-9】字符輸出一。#include<stdio.h>main(){charc=199;printf(″c=%d,c=%c\n″,c,c);return0;}輸出為:

c=-57,c=‖-

【例3-10】字符輸出二。#include<stdio.h>main(){unsignedcharc=199;printf(″c=%d,c=%c\n″,c,c);return0;}輸出為:

c=199,c=‖-

2.字符常量我們已知字符常量是用單引號(hào)括起來(lái)的字符,這對(duì)于可顯示字符來(lái)說(shuō)很容易表示,但對(duì)于控制字符怎樣表示呢?在C語(yǔ)言中沒(méi)有相應(yīng)的直接形式顯示這些字符,但可以換一種形式來(lái)表示它們,即用轉(zhuǎn)義字符來(lái)表示。轉(zhuǎn)義字符是以反斜杠′\′開(kāi)頭,后面加其他字符。反斜杠的作用是把后面的字符賦以新的含義(即轉(zhuǎn)義)。以′\′開(kāi)頭定義的字符有三種情況:非顯示字符(控制字符)、可顯示字符和字符的數(shù)值表示,如表3-1所示。

【例3-11】轉(zhuǎn)義字符的輸出。#include<stdio.h>main(){printf(″Thisisaprogram\n″);printf(″\thisis\ba\012program\n″);printf(″\″first\\second\″″);return0;}運(yùn)行輸出:Thisisaprogramhisiaprogram″first\second″其中,“\t”是水平制表符,“\b”是退格符,“\012”和“\n”都是換行符。要想輸出“\”,必須寫(xiě)成“\\”;要想輸出“"”,必須寫(xiě)成“\"”。

3.字符和字符串前面已指出,字符串是用雙引號(hào)括起來(lái)的字符序列。字符和字符串有著本質(zhì)的區(qū)別:

(1)字符用單引號(hào)括起來(lái),而字符串用雙引號(hào)括起來(lái)。

(2)單引號(hào)括起來(lái)的只有一個(gè)字符,而雙引號(hào)括起來(lái)的有多個(gè)字符。不管顯示出來(lái)的有多少個(gè)字符,字符串都由一個(gè)看不見(jiàn)的字符′\0′結(jié)束,因此′a′和″a″并不相同。前者是字符,后者是字符串,″a″中有兩個(gè)字符:′a′和′\0′?!鋅0′是ASCII碼值為0的字符,是“空字符”。C語(yǔ)言規(guī)定,字符串必須以′\0′結(jié)束,這個(gè)字符是系統(tǒng)自動(dòng)加上去的,不是顯式輸入的。系統(tǒng)據(jù)此可以判斷字符串是否結(jié)束。因此″a″在內(nèi)存中的形式是a\0它占有兩個(gè)字節(jié),長(zhǎng)度為2,而′a′的長(zhǎng)度為1。因此如果有定義:

charc;則

c=″a″;就是錯(cuò)誤的。3.2.3float和double類(lèi)型通常稱(chēng)float為浮點(diǎn)類(lèi)型,而稱(chēng)double為雙精度類(lèi)型,它們都用來(lái)表示實(shí)數(shù),差別只在于長(zhǎng)短不同,因而所能表示的數(shù)的范圍也不同。

1.浮點(diǎn)型數(shù)據(jù)的兩種表示形式對(duì)于一個(gè)實(shí)型常量,可以用兩種形式表示它,即十進(jìn)制小數(shù)形式和指數(shù)形式。

(1)十進(jìn)制小數(shù)形式,如123.45、-0.001。

(2)指數(shù)形式,其組成格式為:

〈尾數(shù)部分〉e(或E)〈指數(shù)部分〉其含義為:

〈尾數(shù)部分〉×10〈指數(shù)部分〉這幾部分的書(shū)寫(xiě)規(guī)則是:①尾數(shù)部分不能省略,即e(或E)前必須有數(shù)據(jù)。②指數(shù)部分必須是整數(shù)。③尾數(shù)可以只有整數(shù)部分或只有小數(shù)部分。④指數(shù)、尾數(shù)都可以帶符號(hào),如省略符號(hào)則隱含為正。例如:123e2、1.23E4、.123e5、123000E-1等都是正確的書(shū)寫(xiě)形式,且代表同一個(gè)數(shù)12300;而3E22.5、-e-3等都是錯(cuò)誤的指數(shù)形式。雖然同一個(gè)實(shí)數(shù)的指數(shù)形式可以有多種,但只有一種形式是規(guī)格化的,即尾數(shù)部分只有一位整數(shù)的形式,如1.23e4。浮點(diǎn)型數(shù)據(jù)在內(nèi)存中也是按指數(shù)形式存儲(chǔ)的。對(duì)于有4個(gè)字節(jié)32位的實(shí)型數(shù)據(jù),一般情況是尾數(shù)部分24位,指數(shù)部分8位,其中各含一位符號(hào)位,即

2.浮點(diǎn)型變量的分類(lèi)浮點(diǎn)型變量分單精度(float)、雙精度(double)和長(zhǎng)雙精度(longdouble)三種,它們的長(zhǎng)度、精度及取值范圍如表3-2所示。在ANSIC中,浮點(diǎn)常量被默認(rèn)為double類(lèi)型,如果要顯式地指明某浮點(diǎn)數(shù)為float類(lèi)型,必須加上后綴f或F,如1.6f、3.7F等。在不需要太大的精度時(shí),這種表示可以加快運(yùn)算速度,節(jié)省內(nèi)存空間。3.2.4變量賦初值前面已介紹了三種數(shù)據(jù)類(lèi)型,用類(lèi)型名可以定義相應(yīng)的變量。根據(jù)先定義后使用的原則,在定義變量之后,可以對(duì)它進(jìn)行處理。如:inti,j;i=3;j=3;通過(guò)賦值語(yǔ)句,使i、j具有數(shù)值3。我們還可以把二者結(jié)合起來(lái),即在定義變量的同時(shí)就讓它有一個(gè)值,這就是變量賦初值,如:

inti=3,j=3;程序可以對(duì)i、j的當(dāng)前值進(jìn)行運(yùn)算,當(dāng)然這些值在以后是可以改變的。注意:上面的語(yǔ)句中變量i和j都具有初始值3,能不能把它們連寫(xiě)呢?如:

inti=j=3;答案是:這樣寫(xiě)是錯(cuò)誤的,只能對(duì)它們分別賦初值,即使這些初值都是相同的也不能連寫(xiě)。要使i、j具有相同的值,還可以采用下面的方法:

inti,j; i=j=3;這種寫(xiě)法是合法的,但這和賦初值的含義是不同的。可以定義多個(gè)變量而對(duì)其中個(gè)別變量賦初值:

inti,j=3;則j具有初值3,而i未賦初值,即它的值是不確定的,不能直接使用。3.3C的運(yùn)算符及表達(dá)式

C語(yǔ)言不僅數(shù)據(jù)類(lèi)型豐富,運(yùn)算符也十分豐富,幾乎所有的操作都可作為運(yùn)算符處理。由運(yùn)算符加適當(dāng)?shù)倪\(yùn)算對(duì)象可構(gòu)成表達(dá)式,而表達(dá)式是C程序的重要要素之一,因此掌握好運(yùn)算符的使用對(duì)編寫(xiě)程序是十分重要的。對(duì)于每一個(gè)運(yùn)算符,要注意從兩個(gè)方面去把握:運(yùn)算符的優(yōu)先級(jí)和結(jié)合性。優(yōu)先級(jí)指多個(gè)運(yùn)算符用在同一個(gè)表達(dá)式中時(shí)先進(jìn)行什么運(yùn)算,后進(jìn)行什么運(yùn)算;而結(jié)合性是指運(yùn)算符所需要的數(shù)據(jù)是從其左邊開(kāi)始取還是從右邊開(kāi)始取,因而有所謂“左結(jié)合”和“右結(jié)合”之說(shuō)。本章中我們介紹一些最基本的運(yùn)算符,后面的章節(jié)中將陸續(xù)介紹其他運(yùn)算符。3.3.1算術(shù)運(yùn)算符

1.基本的算術(shù)運(yùn)算符

C語(yǔ)言中基本的算術(shù)運(yùn)算符有:+、-、*、/、%,其含義如表3-3所示。

在算術(shù)運(yùn)算符的使用中有以下兩點(diǎn)需要注意:

(1)除法運(yùn)算符“/”的結(jié)果和其運(yùn)算對(duì)象有關(guān)。如果兩個(gè)運(yùn)算對(duì)象都是符號(hào)相同的整數(shù),則運(yùn)算符“/”的功能是整除,結(jié)果為整數(shù)。整除的含義是舍去小數(shù)部分,只保留整數(shù)部分。兩個(gè)運(yùn)算對(duì)象中如果有一個(gè)是浮點(diǎn)數(shù),則結(jié)果就是浮點(diǎn)數(shù)。如果兩個(gè)運(yùn)算對(duì)象都是整數(shù),但其中有一個(gè)是負(fù)數(shù),另一個(gè)是正數(shù),則一般采用“向零取整”的原則,即按其絕對(duì)值相除后再加負(fù)號(hào)。還應(yīng)注意,在做除法運(yùn)算時(shí),除數(shù)不能為0。如除數(shù)為0,則會(huì)導(dǎo)致致命錯(cuò)誤而使程序以失敗終止。

(2)求模運(yùn)算符“%”要求其運(yùn)算對(duì)象都必須是整數(shù),但可正可負(fù)。對(duì)有負(fù)數(shù)情況的處理有以下一般性的原則:先按其絕對(duì)值求模(|r|%|s|),然后取被除數(shù)r的符號(hào)作為模的符號(hào)。

【例3-12】算術(shù)運(yùn)算的輸出。#include<stdio.h>main(){printf(″5/3=%d,-5/+3=%d\n″,5/3,-5/+3);printf(″3/5=%d,3./5=%f\n″,3/5,3./5);printf(″10%%3=%d,-10%%3=%d,10%%-3=%d,-10%%-3=%d\n″,10%3,-10%3,10%-3,-10%-3);return0;}運(yùn)行輸出:5/3=1,-5/+3=-13/5=0,3./5=0.60000010%3=1,-10%3=-1,10%-3=1,-10%-3=-1由例3-12可知,要輸出一個(gè)“%”,在字符串中必須有兩個(gè)“%”,即“%%”。

2.算術(shù)運(yùn)算符的優(yōu)先級(jí)和結(jié)合性

C語(yǔ)言中算術(shù)運(yùn)算符的優(yōu)先級(jí)和代數(shù)中的規(guī)定是一樣的,并且都是從左向右結(jié)合的,如表3-4所示。例如,有代數(shù)表達(dá)式:

z=bp-r%-q+((a+b)c)÷x-y將其轉(zhuǎn)變成C語(yǔ)言表達(dá)式為

z=b*p-r%-

q+((a+b)*c)/x-

y ①④③②⑧⑤⑥⑦⑨則運(yùn)算時(shí)將按①、②、…⑧、⑨所示的順序進(jìn)行。其中,q前的“-”號(hào)為單目運(yùn)算符,優(yōu)先級(jí)最高,而r前的“-”是代表減運(yùn)算。如何加以區(qū)分呢?凡+、-號(hào)前沒(méi)有數(shù)字或只有*、/、%等級(jí)別較高的運(yùn)算符時(shí),“+”、“-”即為單目運(yùn)算符,否則即為加、減運(yùn)算符。3.3.2自加(++)自減(--)運(yùn)算符

C語(yǔ)言中有兩個(gè)特殊的算術(shù)運(yùn)算符,即自加、自減運(yùn)算符(++和--)。這兩個(gè)運(yùn)算符都是單目運(yùn)算符,它們既可以放在運(yùn)算對(duì)象之前,也可以放在運(yùn)算對(duì)象之后,形成前置形式和后置形式,而運(yùn)算對(duì)象也只能是整型變量。不管前置還是后置,其運(yùn)算結(jié)果都是一樣的,都是把運(yùn)算對(duì)象的值增加1或減少1。設(shè)有整型變量i,則++i、i++都使i值增加1,--i、i--都使i值減少1。既然效果相同,那么區(qū)分前置和后置形式又有何意義呢?其意義不在于它所作用的變量本身,而在于對(duì)變量值的使用。前置形式是先把變量值加(減)1,然后用新的值參與表達(dá)式的運(yùn)算;而后置形式是先用變量的原始值參與表達(dá)式的運(yùn)算,然后再對(duì)變量的值加(減)1。例如有語(yǔ)句:

inti,j=2;則下面運(yùn)算的結(jié)果是i等于3,j也等于3:

i=++j;而下面的運(yùn)算結(jié)果是i等于2,而j等于3:

i=j++;

使用自加、自減運(yùn)算符應(yīng)注意以下幾點(diǎn):

(1)最常見(jiàn)的錯(cuò)誤是把自加、自減運(yùn)算符用在非簡(jiǎn)單整型變量的表達(dá)式上,如++(x+2)、++(-i)等都是錯(cuò)誤的。

(2)自加自減運(yùn)算符的結(jié)合性為:前置時(shí)是自右向左的,后置時(shí)是自左向右的。比如p=-x++等價(jià)于p=-(x++)。這個(gè)表達(dá)式的意思是先用x變量的當(dāng)前值加負(fù)號(hào)賦給p,而后x再加1。該表達(dá)式并不等價(jià)于p=(-x)++,因?yàn)檫@樣就使++作用在表達(dá)式-x上了,這是(1)中指出的錯(cuò)誤。

(3)如果兩個(gè)運(yùn)算對(duì)象之間連續(xù)出現(xiàn)多個(gè)運(yùn)算符,則C語(yǔ)言采用“最長(zhǎng)匹配”原則,即在保證有意義的前提下,從左到右盡可能多地將字符組成一個(gè)運(yùn)算符。因此i+++j就被解釋成(i++)+j而不是i+(++j)。同樣,i++++j被解釋成(i++)++j;i+++++j被解釋成((i++)++)+j。而這兩種情況都是錯(cuò)誤的。正確的寫(xiě)法應(yīng)該是在連續(xù)的運(yùn)算符中間的適當(dāng)?shù)胤皆黾涌崭穹指舴蚣永ㄌ?hào),使分開(kāi)的部分成為有意義的運(yùn)算對(duì)象。比如應(yīng)把i+++++j寫(xiě)成i+++++j或(i++)+(++j)。

(4)對(duì)所有簡(jiǎn)單類(lèi)型的變量都可以進(jìn)行自加、自減運(yùn)算。

【例3-13】自加運(yùn)算。#include<stdio.h>main(){intp,x=3;charc=′a′;

floatf=3.2;p=-x+++1;

printf(″p=%d,x=%d\n″,p,x);printf(″c=%c\n″,++c);printf(″f=%f\n″,++f);return0;}運(yùn)行輸出:p=-2,x=4c=bf=4.200000

(5)ANSIC并沒(méi)有規(guī)定所有運(yùn)算符操作數(shù)的計(jì)算順序。例如對(duì)于語(yǔ)句:i=m*n+p*q;,根據(jù)運(yùn)算符的優(yōu)先級(jí)和結(jié)合性可知,它等同于i=(m*n)+(p*q);,但對(duì)于m*n和p*q誰(shuí)先進(jìn)行計(jì)算,C并未明確規(guī)定,不同的編譯系統(tǒng)都有不同的規(guī)定。因此在一個(gè)語(yǔ)句中如果要對(duì)一個(gè)變量前后使用多次,而且前后值不同,則應(yīng)避免使用自增、自減運(yùn)算符。比如:

i=1; m=++i*(i+1);對(duì)于這個(gè)表達(dá)式,編譯系統(tǒng)可能:①先計(jì)算++i,再計(jì)算i+1;②先計(jì)算i+1,后計(jì)算++i。對(duì)于①,結(jié)果是m=2*(2+1)=6;而對(duì)于②,結(jié)果是m=2*(1+1)=4。為避免產(chǎn)生這種二義性,應(yīng)當(dāng)把它們分成兩個(gè)表達(dá)式,明晰地表達(dá)程序員的意圖。如果想得到①的結(jié)果,可寫(xiě)成:++i;m=i*(i+1)如果想得到②的結(jié)果,可寫(xiě)成:j=i+1;m=j*(i+1);i++;另外,在一個(gè)表達(dá)式中若同一個(gè)變量前后出現(xiàn)多次并且還被施以自加運(yùn)算,則這樣的表達(dá)式的運(yùn)算結(jié)果還會(huì)因變量出現(xiàn)地點(diǎn)的不同而不同。如inti=5,j;j=i+++i+++i++;printf(″j=%d\n″,j);printf(″i=%d\n″,i);則結(jié)果為

j=15i=8這里,表達(dá)式中的三個(gè)i都以其初值5參與運(yùn)算,相當(dāng)于5+5+5。而將該表達(dá)式作為printf()函數(shù)的參數(shù)時(shí),就會(huì)出現(xiàn)不同的情況:inti=5;printf(″sum=%d\n″,i+++i+++i++);printf(″i=%d\n″,i);則結(jié)果為sum=18i=8在作為函數(shù)參數(shù)的表達(dá)式中,每個(gè)參與運(yùn)算的i的值都是不同的,第一個(gè)i以其初值5參與運(yùn)算,同時(shí)進(jìn)行++運(yùn)算,使其值變?yōu)?,作為第二個(gè)i的值參與運(yùn)算。同樣再進(jìn)行++運(yùn)算后,使其值變?yōu)?,作為第三個(gè)i的值參與運(yùn)算,相當(dāng)于5+6+7。編寫(xiě)程序應(yīng)當(dāng)使用通用的規(guī)則,把可讀性放在第一位,不要使用依賴于不同編譯系統(tǒng)的規(guī)則去編寫(xiě)那些晦澀難懂、令人捉摸不定的程序,因此不要去編寫(xiě)(i++)+(i++)+(i++)以及printf(″%d,%d″,i,i++);這樣的表達(dá)式和語(yǔ)句。3.3.3關(guān)系及邏輯運(yùn)算符關(guān)系運(yùn)算符用來(lái)比較兩個(gè)運(yùn)算對(duì)象的大小,比較的結(jié)果是真和假兩個(gè)邏輯值,而邏輯運(yùn)算符的操作對(duì)象和結(jié)果也都是邏輯值,因此這兩種運(yùn)算符在使用時(shí)有著密切的聯(lián)系。

1.關(guān)系運(yùn)算符關(guān)系運(yùn)算符又分為兩類(lèi):相等判斷運(yùn)算符和不相等判斷運(yùn)算符,它們分別是:

(1)不相等判斷運(yùn)算符:>(大于)、>=(大于等于)、<(小于)、<=(小于等于);

(2)相等判斷運(yùn)算符:==(等于)、!=(不等于)。關(guān)系運(yùn)算符的優(yōu)先級(jí)低于算術(shù)運(yùn)算符,而在其內(nèi)部,不相等判斷又高于相等判斷,但它們都高于賦值運(yùn)算符。關(guān)系運(yùn)算符的結(jié)合性是從左向右的。兩個(gè)對(duì)象比較的結(jié)果是真或假這兩個(gè)邏輯值之一,它們?cè)贑語(yǔ)言中是這樣表示的:數(shù)字0表示假,非0表示真,比如1、4、′a′等都表示真,這似乎是不可確定的,但關(guān)系運(yùn)算產(chǎn)生的結(jié)果都是確定的,真就是1,而不是別的值。

【例3-14】關(guān)系運(yùn)算符。#include<stdio.h>main(){inta,b,c;a=b=c=10;a=b==c;printf(″a=%d,b=%d,c=%d\n″,a,b,c);printf(″a==(…):%d\n″,a==(b=c++*2));printf(″a=%d,b=%d,c=%d\n″,a,b,c);a=b++>=++b>c++;printf(″a=%d,b=%d,c=%d\n″,a,b,c);return0;}運(yùn)行輸出:a=1,b=10,c=10a==(…):0a=1,b=20,c=11a=0,b=22,c=12第二個(gè)printf語(yǔ)句輸出的是一個(gè)比較結(jié)果,比較運(yùn)算符右邊的運(yùn)算對(duì)象又是個(gè)復(fù)雜的運(yùn)算,結(jié)果b、c的值都有改變,這反映在第三個(gè)printf語(yǔ)句中。在a=b++>=++b>c++中,按照運(yùn)算符的優(yōu)先級(jí)和結(jié)合性,先進(jìn)行賦值號(hào)右邊的運(yùn)算。首先做b++和++b的大于等于(>=)比較,把比較的結(jié)果(1或0)再和c++進(jìn)行大于(>)比較,最后把比較的結(jié)果賦給a。在b++>=++b中,先把第一個(gè)b的值(20)作為和后面比較的數(shù)據(jù),同時(shí)它的值又自動(dòng)加1變成了21,第二個(gè)b值是在21的基礎(chǔ)上再進(jìn)行自加運(yùn)算,因而其值為22。對(duì)于由兩個(gè)字符構(gòu)成的比較運(yùn)算符,在使用中常見(jiàn)的錯(cuò)誤是:

(1)把兩個(gè)字符的次序?qū)戭嵉?,?gt;=、!=、<=寫(xiě)成=>、=!、=<。

(2)在兩個(gè)字符之間加空格,把>=、!=、<=、==寫(xiě)成>=、!=、<=、==。今后凡是由兩個(gè)以上字符構(gòu)成的運(yùn)算符,在使用中都要注意防止出現(xiàn)上面兩種錯(cuò)誤。

(3)把相等運(yùn)算符誤寫(xiě)成賦值運(yùn)算符,即把==寫(xiě)成=,這也是初學(xué)者常犯的錯(cuò)誤。

2.邏輯運(yùn)算符

C語(yǔ)言提供了三個(gè)邏輯運(yùn)算符,按由高到低的優(yōu)先級(jí)次序排列如下:

! 邏輯非(把邏輯值進(jìn)行翻轉(zhuǎn),相當(dāng)于NOT) && 邏輯與(求兩個(gè)邏輯值的與,相當(dāng)于乘運(yùn)算AND) ‖ 邏輯或(求兩個(gè)邏輯值的或,相當(dāng)于加運(yùn)算OR)其中,!為單目運(yùn)算符,&&、‖為雙目運(yùn)算符,其功能和用法可由表3-5的真值表說(shuō)明。表中,e1、e2為邏輯表達(dá)式或關(guān)系表達(dá)式,具有0或非0的值。前已指出,可以用非0來(lái)表示真,不一定是1,但是在用邏輯運(yùn)算符作用后,就一定是0或1了。比如3&&′a′‖0的結(jié)果為1,!5的結(jié)果為0。注意:如再對(duì)!5求非,!(!5)的值是1而不是5,因此在一般情況下,當(dāng)x不是0或1時(shí),!!x不等于x。我們可以把到目前為止我們見(jiàn)過(guò)的運(yùn)算符放在一塊,這樣可以查看其在優(yōu)先級(jí)中所處的位置,如圖3-3所示。邏輯運(yùn)算符的結(jié)合性:除!是右結(jié)合外,&&和‖均為左結(jié)合,如!!x等于!(!x),a‖b‖c等于(a‖b)‖c。程序中使用關(guān)系運(yùn)算符時(shí)要注意返回結(jié)果是用0、1來(lái)表示真假值的,不要用常規(guī)的數(shù)學(xué)知識(shí)去思考和理解。圖3-3運(yùn)算符的優(yōu)先級(jí)!(非)高算術(shù)運(yùn)算符關(guān)系運(yùn)算符

&&(與)‖(或)=(賦值)低

【例3-15】邏輯運(yùn)算符一。#include<stdio.h>main(){inti=7,m,n;m=!!i;n=(3<i<6);printf(″i=%d,m=%d,n=%d\n″,i,m,n);return0;}運(yùn)行輸出:

i=7,m=1,n=1雖然經(jīng)過(guò)!!i運(yùn)算,但i本身的值并沒(méi)有改變,它返回給m的只是個(gè)中間結(jié)果。!!i=!(!7)=!0=1,所以m值是1;3<i<6即3<7<6,從數(shù)學(xué)上看這個(gè)不等式的結(jié)果應(yīng)是假的,但在C語(yǔ)言中卻是這樣處理的:

(3<i<6)=((3<i)<6)=(1<6)=1事實(shí)上,在這里不論i為何值,3<i的結(jié)果一定是0或1,它們都小于6,因此最后的結(jié)果為1,這就是n的值。根據(jù)邏輯運(yùn)算符&&和‖的功能及結(jié)合性,對(duì)邏輯表達(dá)式進(jìn)行求值的時(shí)候,常用所謂的“懶惰求值法”,即只要能判斷出邏輯表達(dá)式的真假即停止向后進(jìn)行運(yùn)算?!皯卸枨笾捣ā敝饕福?/p>

(1)a&&b&&c:當(dāng)求得a值為假時(shí)即停止對(duì)b、c的求值,因?yàn)榇藭r(shí)已可斷定整個(gè)表達(dá)式為假了;只有當(dāng)a為真時(shí)才去求b,只有當(dāng)a、b全為真時(shí)才去求c。

(2)a‖b‖c:當(dāng)求得a值為真時(shí)即停止對(duì)b、c的求值,因?yàn)榇藭r(shí)已可斷定整個(gè)表達(dá)式為真了;只有當(dāng)a為假時(shí)才去求b,只有當(dāng)a、b皆假時(shí)才去求c。

【例3-16】邏輯運(yùn)算符二。#include<stdio.h>main(){inta,b,c;a=b=c=1;++a‖++b&&++c;printf(″(1)a=%d,b=%d,c=%d\n″,a,b,c);a=b=c=1;++a&&++b‖++c;printf(″(2)a=%d,b=%d,c=%d\n″,a,b,c);a=b=c=1;++a&&++b&&++c;printf(″(3)a=%d,b=%d,c=%d\n″,a,b,c);a=b=c=-1++a&&++b‖++c;printf(″(4)a=%d,b=%d,c=%d\n″,a,b,c);a=b=c=-1;++a‖++b&&++c;printf(″(5)a=%d,b=%d,c=%d\n″,a,b,c);a=b=c=-1;++a&&++b&&++c;printf(″(6)a=%d,b=%d,c=%d\n″,a,b,c);return0;}運(yùn)行輸出:(1)a=2,b=1,c=1(2)a=2,b=2,c=1(3)a=2,b=2,c=2(4)a=0,b=-1,c=0(5)a=0,b=0,c=-1(6)a=0,b=-1,c=-1

注意:輸出(4)是求++a&&++b‖++c,++a等于0僅說(shuō)明不需要求b就可知++a&&++b為假,但還不能說(shuō)整個(gè)表達(dá)式為假,還必須對(duì)‖后面的++c進(jìn)行運(yùn)算。因?yàn)椤?&都是嚴(yán)格地按從左到右的順序進(jìn)行運(yùn)算的,即使它們出現(xiàn)在同一個(gè)表達(dá)式中也是如此,當(dāng)‖出現(xiàn)在&&之前時(shí),也不會(huì)因?yàn)?&的優(yōu)先級(jí)高而先對(duì)&&的運(yùn)算對(duì)象進(jìn)行運(yùn)算,因此++a‖++b&&++c等同于++a‖(++b&&++c),所以有(1)和(5)的輸出結(jié)果。由關(guān)系運(yùn)算符和邏輯運(yùn)算符可以表示復(fù)雜的邏輯條件,這在程序設(shè)計(jì)中是經(jīng)常用到的。比如要表示某一年份year是否為閏年,根據(jù)天文學(xué)知識(shí),只要符合下列條件之一即為閏年:

(1)年份year能被4整除,但不能被100整除;

(2)年份year能被400整除。據(jù)此可以寫(xiě)出邏輯表達(dá)式:

(year%4==0&&year%100!=0)‖year%400==0根據(jù)運(yùn)算符的優(yōu)先級(jí),式中的括號(hào)是可以不要的,加上是為了清晰。3.3.4賦值運(yùn)算符要使一個(gè)變量得到值或改變它的值,除了可以用scanf函數(shù)輸入外,也可以很方便地用賦值運(yùn)算符實(shí)現(xiàn)。前面我們已介紹過(guò)賦值運(yùn)算符的基本使用,現(xiàn)在做進(jìn)一步的說(shuō)明。

1.一般的賦值運(yùn)算符在C語(yǔ)言中,賦值運(yùn)算符為=,由它可以構(gòu)成賦值表達(dá)式:

〈變量名〉=〈表達(dá)式〉賦值運(yùn)算就是首先計(jì)算右邊表達(dá)式的值,然后把它賦給左邊的變量。賦值表達(dá)式的值就是左邊變量最后的值。如表達(dá)式a=1和b=′a′+1,a、b的值分別是1和98。賦值運(yùn)算符右邊的表達(dá)式本身又可能是賦值表達(dá)式,也就是說(shuō)賦值表達(dá)式可以遞歸定義,于是就可以出現(xiàn)a=b=c=10這樣的寫(xiě)法。如何分析這種形式呢?這涉及到賦值運(yùn)算符的結(jié)合性問(wèn)題。賦值運(yùn)算符是右結(jié)合的,因此a=b=c=10等價(jià)于a=(b=(c=10))。最右邊的賦值運(yùn)算使c的值為10,它也是這個(gè)小表達(dá)式的值,把這個(gè)值再賦給b,它的值10也是右邊第二個(gè)賦值表達(dá)式的值,最后再把這個(gè)值賦給a,a的值為10,這也是整個(gè)表達(dá)式的值。作為過(guò)程結(jié)果,a、b、c的值都是10,就像是把最右邊表達(dá)式的值連續(xù)地賦給了它左邊的各個(gè)變量一樣。賦值號(hào)兩邊的部分分別稱(chēng)為“左值”和“右值”,只有變量才能充當(dāng)左值,非簡(jiǎn)單變量的表達(dá)式不能作左值使用。因此,a++=1;、a=b++=c++=2;等都是錯(cuò)誤的。但++a=1;卻是正確的,因?yàn)檫@是先對(duì)a進(jìn)行加1運(yùn)算,其值增加1,它本身仍然是個(gè)變量,所以可以充當(dāng)左值;而a++相當(dāng)于a+1,已不是個(gè)簡(jiǎn)單變量了,所以不能作左值。賦值操作也是一種破壞性輸入,即不管左邊變量原來(lái)具有什么樣的值,結(jié)果都要變成右邊表達(dá)式的值。如:inta=5,b=6;a=b+3;b=a-2;a,b的初值分別是5和6,但經(jīng)過(guò)賦值運(yùn)算之后,a和b的值分別變?yōu)?和7。賦值運(yùn)算符的優(yōu)先級(jí)是除逗號(hào)運(yùn)算符之外最低的。

2.賦值運(yùn)算中的類(lèi)型轉(zhuǎn)換如果賦值運(yùn)算符兩邊的類(lèi)型不一致,則在賦值的時(shí)候要對(duì)右邊表達(dá)式的類(lèi)型進(jìn)行轉(zhuǎn)換,使之適應(yīng)左邊變量的要求,或者說(shuō)用左邊變量的類(lèi)型去剪裁改造右邊的表達(dá)式。為了便于表達(dá),我們做如下的約定: [類(lèi)型1]←(類(lèi)型2)表示把類(lèi)型2的值賦給類(lèi)型1的變量。具體地有以下幾種情況:

(1)[int]←(float,double):此時(shí)去掉實(shí)數(shù)的小數(shù)部分,只把其整數(shù)部分賦給整型變量。如:

inti=9.87;結(jié)果i中只有整數(shù)9,舍掉的小數(shù)部分并不進(jìn)行四舍五入處理。

(2)[float]←(int)和[double]←(int):變量中的整數(shù)部分是右邊表達(dá)式的值,而小數(shù)部分是相應(yīng)個(gè)數(shù)的

0。如:

floatf=15; doubled=15;則有:

f=15.000000(6個(gè)0) d=15.00…0(14個(gè)0)

(3)[float]←(double):在float類(lèi)型所能容納的范圍之內(nèi),把double數(shù)值的前7位放入float型變量中,超過(guò)范圍則出錯(cuò)。[double]←(float):在double變量中,有效位數(shù)擴(kuò)展到16位,數(shù)值不變。

(4)[int]←(unsignedchar):int類(lèi)型占兩個(gè)字節(jié),char類(lèi)型占一個(gè)字節(jié),賦值時(shí)把字符放入整型變量的低8位,高8位全補(bǔ)0,以保證是正整數(shù)。例如:

inti;unsignedcharc=′\376′;i=c;則其內(nèi)存表示為:[int]←(char):是把有符號(hào)的字符賦給整型變量。這時(shí),如字符符號(hào)位是0,則整數(shù)的高8位全補(bǔ)0;如字符符號(hào)位是1,則整數(shù)高8位全補(bǔ)1,這稱(chēng)為“符號(hào)擴(kuò)展”,目的是為了保證賦值后的數(shù)值保持不變。再如:

inti;charc=′\376′;i=c;則賦值后的內(nèi)存結(jié)果為之所以要采用符號(hào)擴(kuò)展的原則,是為了保證在以十進(jìn)制整數(shù)格式%d輸出i和c時(shí),它們都具有相同的值-2。

(5)[char]←(int,shortint,longint):只把整數(shù)的低8位送到字符變量中,其余全部截掉,當(dāng)整數(shù)大于255(低8位的最大值)時(shí),賦值在變量中會(huì)改變?cè)瓉?lái)的值,如:

inti=256;charc;c=i; printf(″i=%d,c=%d\n″,i,c);則輸出為

i=256,c=0內(nèi)存表示為

(6)[long]←(int):把int類(lèi)型數(shù)值送入long類(lèi)型的低16位中,高16位按“符號(hào)擴(kuò)展”的原則處理。 [int]←(long):把long的低16位送入int型變量,高16位截掉,如高16位中仍有數(shù)據(jù),則賦值在變量中有可能改變?cè)瓉?lái)的值。

(7)[int]←(unsignedint)、[long]←(unsignedlong)及[short]←(unsignedshort):這類(lèi)賦值的特點(diǎn)是兩邊的長(zhǎng)度相等,但取值范圍不同,右邊的正數(shù)范圍要比左邊大一倍,因此只有在左邊的正數(shù)范圍內(nèi)賦值才正確,否則所賦的正值在變量中會(huì)得到負(fù)的結(jié)果。例如:intb;unsignedinta=65535;b=a;printf(″a=%u,b=%d\n″,a,b);結(jié)果為a=65535,b=-1內(nèi)存表示為

(8)[unsignedin]←(int)、[unsignedlong]←(long)及[unsignedshort]←(short):這是和(7)相反的賦值,可以照原值全部傳送,但若傳送負(fù)數(shù),則接收者會(huì)得到一個(gè)正數(shù)的結(jié)果,其原因在于把原來(lái)的符號(hào)位也當(dāng)成了數(shù)值位。例如:unsignedinta;intb=-1;a=b;printf(″b=%d,a=%u\n″,b,a);則輸出為

b=-1,a=65535內(nèi)存表示為

3.復(fù)合的賦值運(yùn)算符在普通賦值運(yùn)算符的前面加上其他成分,可構(gòu)成復(fù)合的賦值運(yùn)算符。其一般形式是:

〈變量名〉@=〈表達(dá)式〉其中,@可以是如下運(yùn)算符之一:+、-、*、/、%、、、&、|、^。前5個(gè)是算術(shù)運(yùn)算符,后5個(gè)是位運(yùn)算符(將在后面章節(jié)中介紹)。復(fù)合賦值運(yùn)算的語(yǔ)義是:

〈變量名〉=〈變量名〉@(〈表達(dá)式〉)即把變量的原值和表達(dá)式的值進(jìn)行由@指出的運(yùn)算,再把運(yùn)算結(jié)果賦給變量。如設(shè)a的初值為3,則a*=6就等價(jià)于a=a*6,即a的終值為18。因此這里要求變量一定要具有初值,如沒(méi)有初值,則放入復(fù)合賦值運(yùn)算表達(dá)式中就是錯(cuò)誤的。

注意:

在把復(fù)合賦值形式轉(zhuǎn)換成普通賦值形式時(shí),對(duì)原表達(dá)式最好加括號(hào),否則有可能出錯(cuò)。如:

x*=y+4;這種寫(xiě)法是正確的,但當(dāng)把它變成普通形式而對(duì)表達(dá)式y(tǒng)+4不加括號(hào)時(shí)會(huì)變成:

x=x*y+4;這就和原意大相徑庭了。應(yīng)該寫(xiě)成:

x=x*(y+4);這樣才正確。在有多個(gè)復(fù)合賦值的表達(dá)式中,要時(shí)刻注意變量的當(dāng)前值,并且當(dāng)前所考慮的復(fù)合賦值運(yùn)算符兩邊的同一變量應(yīng)該具有相同的值。例如,設(shè)a=8,求a+=a-=a*a的結(jié)果。根據(jù)賦值運(yùn)算符右結(jié)合的特點(diǎn),原式等價(jià)于:a+=(a=a-(a*a)),計(jì)算最右邊的算術(shù)表達(dá)式后得:a+=(a=-56),此時(shí)+=兩邊的a應(yīng)該以共同的新值-56參與運(yùn)算,而不再是原來(lái)的8了。于是變?yōu)椋篴=a+a=-56-56=-112。這是正確的結(jié)果,而不要理解成:a=8-56=-48。當(dāng)作為左值的變量有前置的++、--運(yùn)算符時(shí),則先對(duì)變量進(jìn)行自加、自減運(yùn)算,再將運(yùn)算結(jié)果和右邊的表達(dá)式進(jìn)行相應(yīng)運(yùn)算。如a=8,則++a+=1就相當(dāng)于a=(++a)+1=9+1=10。3.3.5逗號(hào)運(yùn)算符逗號(hào)在C語(yǔ)言中主要起兩個(gè)作用,一個(gè)是作為分隔符,一個(gè)是作為運(yùn)算符。

1.逗號(hào)分隔符把兩個(gè)對(duì)象分開(kāi)可以用多種符號(hào),如空格、反斜杠等,但多用逗號(hào)作分隔符。在變量的定義和函數(shù)的參數(shù)中都用到了逗號(hào)分隔符。如:

inti,j,k;charc1,c2,c3; result=max(a,b);這里它的作用是把同類(lèi)型的變量名分開(kāi),把函數(shù)的各個(gè)參數(shù)分開(kāi)。

2.逗號(hào)運(yùn)算符作為運(yùn)算符,它是把兩個(gè)對(duì)象“連接起來(lái)”,使之成為一個(gè)逗號(hào)表達(dá)式。其一般形式是:

〈表達(dá)式1〉,〈表達(dá)式2〉,…,〈表達(dá)式n〉例如:

i=1,j=0,sum=0,m=2*i+3是一個(gè)由四個(gè)賦值表達(dá)式構(gòu)成的逗號(hào)表達(dá)式。逗號(hào)運(yùn)算符的優(yōu)先級(jí)是最低的,它的結(jié)合性是從左向右的。因此在求表達(dá)式的值時(shí),是從左向右進(jìn)行計(jì)算的,后面表達(dá)式的計(jì)算可以利用前面表達(dá)式的計(jì)算結(jié)果,而最后那個(gè)表達(dá)式的值就作為整個(gè)表達(dá)式的值,其類(lèi)型也是整個(gè)表達(dá)式的類(lèi)型。因此上面的逗號(hào)表達(dá)式是先對(duì)i=1計(jì)算,求出i的值用于后面表達(dá)式的計(jì)算,即求出m=5,這也是整個(gè)逗號(hào)表達(dá)式的值。3.3.6sizeof運(yùn)算符

sizeof是一個(gè)單目運(yùn)算符,其作用是求運(yùn)算對(duì)象所具有的字節(jié)數(shù)。它的使用形式是:

sizeof(〈運(yùn)算對(duì)象〉)或sizeof〈運(yùn)算對(duì)象〉其中,運(yùn)算對(duì)象可以是數(shù)據(jù)類(lèi)型名、變量名、常量名等。變量、常量的大小實(shí)際上是它所屬類(lèi)型的大小。在求字符串常量的大小時(shí),包括了看不見(jiàn)的符號(hào)′\0′。若運(yùn)算對(duì)象是類(lèi)型名或由運(yùn)算符連成的表達(dá)式,則必須用括號(hào)括起來(lái);如果運(yùn)算對(duì)象是簡(jiǎn)單常量或變量,則括與不括均可,如sizeofi++也是合法的,但最好加上括號(hào)。

sizeof運(yùn)算符僅求其對(duì)象的長(zhǎng)度,并不對(duì)運(yùn)算對(duì)象進(jìn)行求值計(jì)算,比如sizeof(++i)并不對(duì)i進(jìn)行自加運(yùn)算。

【例3-17】sizeof運(yùn)算符。#include<stdio.h>main(){inti=162;floaty=0.0;printf(″sizeof(++i)=%d,i=%d\n″,sizeof(++i),i);printf(″sizeof(162)=%d\n″,sizeof(162));printf(″sizeof(\″China\″)=%d\n″,sizeof(″China″));printf(″sizeof(int)=%d\n″,sizeof(int));printf(″sizeof(float)=%d\n″,sizeof(float));printf(″sizeof(double)=%d\n″,sizeof(double));printf(″sizeof(1.1)=%d\n″,sizeof(1.1));printf(″sizeof(y=2*i+6.0)=%d\n″,sizeof(y=2*i+6.0));

printf(″y=%f\n″,y);return0;}運(yùn)行輸出:sizeof(++i)=2,i=162sizeof(162)=2sizeof(″China″)=6sizeof(int)=2sizeof(float)=4sizeof(double)=8sizeof(1.1)=8sizeof(y=2*i+6.0)=4y=0.000000因?yàn)榭紤]到了′\0′,所以sizeof(″China″)=6。編譯程序總是把浮點(diǎn)常數(shù)作為double類(lèi)型來(lái)處理,因此有sizeof(1.1)=8。

sizeof(y=2*i+6.0)=4是因?yàn)橘x值運(yùn)算符的左值y的類(lèi)型是float,占4字節(jié),返回的是y的類(lèi)型的長(zhǎng)度。

y=0.000000表明sizeof運(yùn)算并不對(duì)運(yùn)算對(duì)象求值。

雖然sizeof的使用像是一個(gè)函數(shù)調(diào)用,但它只是個(gè)運(yùn)算符,不是函數(shù),它沒(méi)有函數(shù)調(diào)用方面的開(kāi)銷(xiāo)。3.3.7條件運(yùn)算符條件運(yùn)算符“?:”是C語(yǔ)言中惟一的一個(gè)三目運(yùn)算符,它有三個(gè)運(yùn)算對(duì)象,分別由“?”和“:”把它們連接起來(lái),構(gòu)成一個(gè)條件表達(dá)式。其語(yǔ)法形式是:

〈表達(dá)式1〉?〈表達(dá)式2〉:〈表達(dá)式3〉它的語(yǔ)義如圖3-4所示。圖3-4條件運(yùn)算符的語(yǔ)義整個(gè)條件表達(dá)式的值要么是表達(dá)式2的值,要么是表達(dá)式3的值,全依賴于對(duì)表達(dá)式1的求值而定。表達(dá)式1是條件表達(dá)式,具有真假兩個(gè)值,如其值為真,則計(jì)算表達(dá)式2,并把表達(dá)式2的值作為整個(gè)表達(dá)式的值返回;如其值為假,則把表達(dá)式3的求值結(jié)果返回。條件表達(dá)式可以嵌套和遞歸定義,在這種情況下,應(yīng)先找到?和:,把它的三部分區(qū)別出來(lái),然后按一般方法進(jìn)行計(jì)算求值。條件運(yùn)算符的結(jié)合性是由右向左的。例如:

a>b?a:c>d?c:d等價(jià)于

a>b?a:(c>d?c:d)條件運(yùn)算符的優(yōu)先級(jí)高于賦值運(yùn)算符而低于關(guān)系運(yùn)算符和算術(shù)運(yùn)算符。因此

max=a>b?a:b+1;等價(jià)于

max=(a>b)?a:(b+1);而不等價(jià)于max=(a>b?a:b)+1;條件表達(dá)式中的三個(gè)表達(dá)式的類(lèi)型可以互不相同,條件表達(dá)式的類(lèi)型為表達(dá)式2和表達(dá)式3二者中較高的類(lèi)型。忽視了這一點(diǎn),程序就會(huì)出現(xiàn)錯(cuò)誤的結(jié)果。

【例3-18】條件運(yùn)算符一。#include<stdio.h>main(){intx=10;floaty=5;printf(″%d\n″,x>y?x:y);

return0;}本來(lái)預(yù)期輸出應(yīng)該是10,但結(jié)果卻是0。這是因?yàn)樵跅l件表達(dá)式“x>y?x:y”中,y的類(lèi)型高,因此整個(gè)表達(dá)式的類(lèi)型就應(yīng)該是y的類(lèi)型float,而對(duì)float類(lèi)型數(shù)據(jù)用′%d′控制符是輸出不了結(jié)果的。如果把′%d′換成′%f′,則會(huì)顯示出正確的結(jié)果:10.000000。

【例3-19】條件運(yùn)算符二。#include<stdio.h>main(){inta,b,c;a=b=c=1;a+=b;b+=c;c+=a;printf(″(1)%d\n″,a++>b?a:b);printf(″(2)%d\n″,a>b?c>a++:b-->a?c++:c--);(a>=b>=c)?printf(″AA\n″):printf(″BB\n″);printf(″a=%d,b=%d,c=%d\n″,a,b,c);return0;}運(yùn)行輸出:

(1)2 (2)0 BB a=4,b=2,c=3由復(fù)合賦值運(yùn)算得:a=2,b=2,c=3,在計(jì)算a++>b?a:b中的a++>b為假之后,a就變成了3。表達(dá)式

a>b?c>a++:b-->a?c++:c--等價(jià)于

a>b?c>a++:(b-->a?c++:c--)右結(jié)合的規(guī)則使最右邊的條件表達(dá)式成為一個(gè)整體,但這是否意味著先對(duì)它進(jìn)行計(jì)算呢?答案是否定的。因?yàn)?:、‖、&&和,這四個(gè)運(yùn)算符都嚴(yán)格地按從左向右的順序進(jìn)行運(yùn)算,所以還是先計(jì)算a>b的值,而不是先計(jì)算b-->a的值。從上面還可以看出:條件表達(dá)式中的表達(dá)式2和表達(dá)式

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論