C語言課件:第4章 表達(dá)式_第1頁
C語言課件:第4章 表達(dá)式_第2頁
C語言課件:第4章 表達(dá)式_第3頁
C語言課件:第4章 表達(dá)式_第4頁
C語言課件:第4章 表達(dá)式_第5頁
已閱讀5頁,還剩31頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、1第4章表達(dá)式2表達(dá)式是表示如何計算值的公式。使用運(yùn)算符將操作數(shù)連接起來構(gòu)成公式。操作數(shù)可以是變量、常量和表達(dá)式。運(yùn)算符是構(gòu)成表達(dá)式的基本工具算術(shù)運(yùn)算符:+、-、*、/關(guān)系運(yùn)算符:、邏輯運(yùn)算符:&、|地址運(yùn)算符:& 表達(dá)式可以構(gòu)成表達(dá)式語句,在C語言中有重要應(yīng)用。什么是表達(dá)式 本章要點(diǎn)算術(shù)運(yùn)算符賦值運(yùn)算符自增和自減運(yùn)算符表達(dá)式求值表達(dá)式語句4.1 算術(shù)運(yùn)算符C提供5個二元算術(shù)運(yùn)算符: + 加(addition) - 減(subtraction) * 乘(multiplication) / 除(division) % 取余(remainder)二元算術(shù)運(yùn)算符需要兩個操作數(shù)。兩個一元算術(shù)運(yùn)算符:+

2、 一元正號運(yùn)算符- 一元負(fù)號運(yùn)算符二元算術(shù)運(yùn)算符二元算術(shù)運(yùn)算符允許操作數(shù)為整數(shù)或浮點(diǎn)數(shù),也可以是兩者混合。當(dāng)操作數(shù)為整數(shù)和浮點(diǎn)數(shù)混合,結(jié)果為浮點(diǎn)數(shù)。 9 + 2.5f 結(jié)果為 11.5 6.7f / 2 結(jié)果為 3.35/ 和 % 運(yùn)算符當(dāng)兩個操作數(shù)是整數(shù)時,運(yùn)算符/”會丟掉分?jǐn)?shù)部分來獲取結(jié)果。因此1/2的結(jié)果是 0而不是0.5。運(yùn)算符%要求操作數(shù)是整數(shù),任一個操作數(shù)不是整數(shù),編譯無法通過。把0做為右操作數(shù),會導(dǎo)致未定義行為。當(dāng)運(yùn)算符/和 %用于負(fù)操作數(shù),在C89中其行為由實(shí)現(xiàn)定義(implementation-defined),除法的結(jié)果可以是向上取整,也可以是向下取整。由實(shí)現(xiàn)定義的行為Im

3、plementation-Defined BehaviorC標(biāo)準(zhǔn)中故意對C語言的部分內(nèi)容未加指定,其細(xì)節(jié)由“實(shí)現(xiàn)”(特定平臺上的編譯、鏈接和執(zhí)行軟件)來定義。這是為了保證C的高效性,意味著與硬件相匹配。!盡量避免編寫依賴于實(shí)現(xiàn)定義行為的程序以確??梢浦残?。一元算術(shù)運(yùn)算符一元算術(shù)運(yùn)算符需要一個操作數(shù):i = +1;j = -i;一元正號+運(yùn)算符無任何操作,強(qiáng)調(diào)某個數(shù)值常量是正的經(jīng)典C沒有這個運(yùn)算符。運(yùn)算符的優(yōu)先級算數(shù)運(yùn)算符的優(yōu)先級如下:最高優(yōu)先級:+ - (一元) * / %最低優(yōu)先級:+ - (二元) 例子: i + j * k 等價于 i + (j * k)、 -i * -j 等價于 (-i

4、) * (-j) +i + j / k 等價于 (+i) + (j / k)運(yùn)算符的結(jié)合性當(dāng)表達(dá)式包含兩個或更多個相同優(yōu)先級的運(yùn)算符時,就需要運(yùn)算符的結(jié)合性。運(yùn)算符從左向右結(jié)合時,稱為左結(jié)合性。二元運(yùn)算符 (*, /, %, +, 和-)是左結(jié)合 i - j k 等價于 (i - j) k i * j / k 等價于 (i * j) / k、運(yùn)算符從右向左結(jié)合時,稱為右結(jié)合性。一元運(yùn)算符 ( +和-)是右結(jié)合、 - + i 等價于 -(+i)例: 計算UPC校驗(yàn)位美國和加拿大的貨物使用通用產(chǎn)品代碼 UPC (Universal Product Code):第一個數(shù)字:表示種類。第一組五個數(shù)字:

5、標(biāo)識生產(chǎn)廠商。第二組五個數(shù)字:標(biāo)識產(chǎn)品最后一個數(shù)字:校驗(yàn)位校驗(yàn)位計算第1、3、5、7、9、11位的數(shù)字相加。第2、4、6、8、10位的數(shù)字相加。第一次加的結(jié)果乘3,和第二次加的結(jié)果相加。把結(jié)果減1,再除10取余數(shù)。最后用9減余數(shù),得到校驗(yàn)位。例: 計算UPC校驗(yàn)位校驗(yàn)位計算:第一次的和:0 + 3 + 0 + 1 + 1 + 3 = 8第二次的和:1 + 8 + 0 + 5 + 7 = 21第三步:8*3+21=45第四步:(45-1)%10=4第五步:9-4=5例: 計算UPC校驗(yàn)位(upc.c)11位的UPC要求用戶分三步錄入:Enter the first (single) digit:

6、 0Enter first group of five digits: 13800Enter second group of five digits: 15173Check digit: 5程序不是按1個5位數(shù)來讀取的,而是按照5個1位數(shù)讀入的。使用scanf的 %1d 轉(zhuǎn)換說明,只匹配1位整數(shù)。/* Computes a Universal Product Code check digit */#include int main(void) int d, i1, i2, i3, i4, i5, j1, j2, j3, j4, j5,first_sum, second_sum, total;

7、printf(Enter the first (single) digit: ); scanf(%1d, &d); printf(Enter first group of five digits: ); scanf(%1d%1d%1d%1d%1d, &i1, &i2, &i3, &i4, &i5); printf(Enter second group of five digits: ); scanf(%1d%1d%1d%1d%1d, &j1, &j2, &j3, &j4, &j5); first_sum = d + i2 + i4 + j1 + j3 + j5; second_sum = i1

8、 + i3 + i5 + j2 + j4; total = 3 * first_sum + second_sum; printf(Check digit: %dn, 9 - (total - 1) % 10); return 0; 4.2 賦值運(yùn)算符簡單賦值運(yùn)算符= (Simple assignment)復(fù)合賦值運(yùn)算符 (Compound assignment)4.2.1 簡單賦值v = e,求表達(dá)式e的值,把此值賦給v.e可以是常量、變量或更復(fù)雜的表達(dá)式:i = 5; /* i is now 5 */j = i; /* j is now 5 */k = 10 * i + j; /* k is

9、 now 55 */v和e的類型不同,賦值運(yùn)算符會把e的值轉(zhuǎn)換成v的類型:int i; float f;i = 72.99f; /* i is now 72 */f = 136; /* f is now 136.0 */簡單賦值在C語言中賦值是運(yùn)算符。賦值操作產(chǎn)生結(jié)果,v = e就是賦值運(yùn)算后 v的值。int i; i=72.99f; /* i的值是72,而不是72.99*/副作用(side effect )一個運(yùn)算符如果修改了操作數(shù)的值,說明這種運(yùn)算符有副作用( side effect )簡單賦值運(yùn)算符有副作用,它修改了左操作數(shù)。表達(dá)式 i = 0 把結(jié)果賦給了(副作用)。多個賦值運(yùn)算符可以

10、串聯(lián)在一起:i = j = k = 0;運(yùn)算符 = 是右結(jié)合,所以上面的表達(dá)式等價于:i = (j = (k = 0);副作用賦值運(yùn)算符串聯(lián)在一起,可能產(chǎn)生非預(yù)期效果:int i;float f;f = i = 33.3f; /*33賦給i,33.0賦給f,結(jié)果不是 33.3 */嵌入式賦值,不便于程序的閱讀,也是隱含錯誤的根源:i = 1;k = 1 + (j = i);printf(%d %d %dn, i, j, k); /* prints 1 1 2 */4.2.2 左值(Lvalues)賦值運(yùn)算符要求它的左操作數(shù)必須是左值。左值表示存儲在計算機(jī)內(nèi)存中的對象,而不是常量或計算的結(jié)果。變

11、量是左值,表達(dá)式10或2 * i不是。下面的例子都是非法的:12 = i; /* WRONG */i + j = 0; /* WRONG */-i = j; /* WRONG */編譯器會檢測這種錯誤,給出錯誤消息 :“invalid lvalue in assignment.”4.2.3 復(fù)合賦值利用變量原值計算新值并又賦給該變量:i = i + 2;C語言使用 += 復(fù)合賦值簡化這種寫法:i += 2; /* same as i = i + 2; */復(fù)合運(yùn)算符-=,*=,/=,%= (其他的參見20章)i -= 2; /* same as i = i - 2; */i *= 2; /*

12、same as i = i * 2; */i /= 2; /* same as i = i / 2; */i %= 2; /* same as i = i % 2; */復(fù)合賦值i *= j + ki = i * j + k還是i = i * (j + k)?復(fù)合賦值i =+ j和 i += j是否一樣?=+不是復(fù)合賦值符, i =+ j等價于i=(+j)復(fù)合賦值復(fù)合賦值運(yùn)算符和=一樣是右結(jié)合i += j +=k 相當(dāng)于i += (j +=k) 4.3 自增和自減運(yùn)算符自增(加1)和自減(減1):i = i + 1;j = j - 1;用復(fù)合運(yùn)算符可以簡化為:i += 1;j -= 1;C提供

13、了更簡化的 +(自增)和-(自減)運(yùn)算符+和- -運(yùn)算符可以作為前綴(+i和-i)使用,也可以作為后綴使用( i+和i-)自增和自減運(yùn)算符前綴會自增和自減變量本身:i = 1;printf(i is %dn, +i); /* i is 2 */printf(i is %dn, i); /* i is 2 */i = 1;printf(i is %dn, -i); /* i is 0 */printf(i is %dn, i); /* i is 0 */后綴是變量先不變,但隨后自增和自減該變量:i = 1;printf(i is %dn, i+); /* i is 1 */printf(i is

14、 %dn, i); /* i is 2 */i = 1;printf(i is %dn, i-); /* i is 1 */printf(i is %dn, i); /* i is 0 */自增和自減運(yùn)算符同一個表達(dá)式中多次使用 + 或 結(jié)果難理解:i = 1;j = 2;k = +i + j+;i,j,k的值為2,3,4。例子:i = 1;j = 2;k = i+ + j+;i,j,k的值為2,3,3。!盡量不使用這種難于理解的書寫方式!4.4 表達(dá)式求值優(yōu)先級名稱符號結(jié)合性1(后綴)自增+左結(jié)合(后綴)自減-2(前綴)自增+右結(jié)合(前綴)自減-一元正號+一元負(fù)號-3乘法類* / %左結(jié)合4

15、加法類+ -左結(jié)合5賦值= *= /= %= += -=右結(jié)合表達(dá)式求值(P43)例子: 優(yōu)先級a = b += c+ - d + -e / -fa = b += (c+) - d + -e / -f 1a = b += (c+) - d + (-e) / (-f) 2a = b += (c+) - d + (-e) / (-f) 3a = b += (c+) - d) + (-e) / (-f) 4(a = (b += (c+) - d) + (-e) / (-f) 5 子表達(dá)式的求值順序有了運(yùn)算符的優(yōu)先級和結(jié)合性規(guī)則,可以把復(fù)雜表達(dá)式分解為子表達(dá)式。C語言沒有定義表達(dá)式的求值順序(除了含有

16、邏輯與和邏輯或運(yùn)算符、條件運(yùn)算符、逗號運(yùn)算符的子表達(dá)式)。表達(dá)式 (a + b) * (c - d)無法確定 (a + b)是否在 (c - d)之前求值。無論表達(dá)式的計算順序如何,大多數(shù)表達(dá)式的值是相同的。30子表達(dá)式的求值順序當(dāng)子表達(dá)式改變了某個操作數(shù)的值時,產(chǎn)生的值可能不一致:a = 5;c = (b = a + 2) - (a = 1);先執(zhí)行b=a+2,則b的值為7,C的值為6。先執(zhí)行a=1,則b的值為3,C的值為2。語句2的執(zhí)行效果未定義。對這種情況,有些編譯器會產(chǎn)生“operation on a may be undefined” 的警告信息。子表達(dá)式的求值順序?yàn)榱吮苊獯祟悊栴},不在子表達(dá)式中使用賦值運(yùn)算符,而是采用分離的賦值表達(dá)式:a = 5;b = a + 2;a = 1;c = b - a;33自增自減也可以改變操作數(shù):i = 2;j = i * i+;結(jié)果未定義,可能是4或6:1)取出第二個i,再自增;2)取出第一個i(新值);3)i的原始值和新值相乘,結(jié)果為6。子表達(dá)式的求值順序未定義行為未定義行為(undefined behavior),和前面的由實(shí)現(xiàn)定義的行為不同。其后果是嚴(yán)重的:不同的編譯器給出的編譯結(jié)果不同。程序可能無法編譯?;蚓幾g了無法運(yùn)行,運(yùn)行了可能崩潰,不

溫馨提示

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

最新文檔

評論

0/150

提交評論