王燕
摘 要:C語言是應(yīng)用最廣的高級程序設(shè)計(jì)語言,其語法靈活,使用便捷。文章在Turbo C環(huán)境下,提出幾種常見的編譯系統(tǒng)糾錯(cuò)無法判斷的問題,分析了幾種運(yùn)算符、語句結(jié)束符和ELSE等,并通過案例來比較分析程序運(yùn)行結(jié)果,為廣大C語言程序?qū)W習(xí)者提供一些參考。
關(guān)鍵詞:C語言;運(yùn)算符;表達(dá)式;判斷條件
C語言既有高級語言的特點(diǎn),又有匯編語言的特點(diǎn),因此它是應(yīng)用最廣的高級程序設(shè)計(jì)語言。用它不但能編寫操作系統(tǒng)軟件,也能開發(fā)各個(gè)領(lǐng)域的應(yīng)用軟件。目前在我國,眾多的本科和高職院校的理工科專業(yè)都把C語言作為一門必修課程。C語言可讀性強(qiáng)、容易維護(hù)、移植性好[1],它具有豐富的運(yùn)算符與數(shù)據(jù)類型,也正因?yàn)檫@些,在學(xué)習(xí)C語言的過程中會出現(xiàn)很多困難和問題。
1 運(yùn)算符與表達(dá)式
運(yùn)算符是表示某種操作的符號,在C語言中運(yùn)算符主要有:賦值運(yùn)算符、算術(shù)運(yùn)算符、邏輯運(yùn)算符等。運(yùn)算符的操作對象稱為運(yùn)算數(shù),表達(dá)式是用運(yùn)算符把運(yùn)算數(shù)連接起來的式子[1]。只是認(rèn)識運(yùn)算符并不難,可是一旦將運(yùn)算符與運(yùn)算數(shù)結(jié)合成表達(dá)式時(shí)就很容易出現(xiàn)知識混淆產(chǎn)生問題而不知該如何入手解決。
1.1 賦值運(yùn)算符“=”和關(guān)系運(yùn)算符“==”
賦值運(yùn)算符“=”在平常生活與基礎(chǔ)學(xué)習(xí)中就是“等于”的意思,但是在C語言中卻不能理解為普通的“等于”的意思,應(yīng)理解為“賦予”或“給予”的意思,而作為判斷平等的“等于”在C語言中用關(guān)系運(yùn)算符“==”來表示。
因?yàn)榱?xí)慣性使然,在編程時(shí)經(jīng)常會出現(xiàn)誤寫“=”作為判斷的“等于”,這樣就使得所要完成的功能語句出錯(cuò),而這種錯(cuò)誤是編譯系統(tǒng)無法判斷出的錯(cuò)誤。
例如:下列程序語句實(shí)現(xiàn)功能是:當(dāng)變量x的值,在運(yùn)行過程中等于0時(shí),輸出錯(cuò)誤提示:error!
“error!”的錯(cuò)誤提示,表面上兩個(gè)只有“=”與“==”不同的語句都沒有什么問題,結(jié)果都是正確的。但是,如果將int x=0變更為int x=1,運(yùn)行結(jié)果卻是:第一句判斷顯示的結(jié)果還是“error!”的錯(cuò)誤提示,第二句判斷沒有顯示輸出。實(shí)際上結(jié)果是很明顯的,當(dāng)x=1時(shí)是不要輸出錯(cuò)誤提示的,而第一句判斷仍然是“error!”的錯(cuò)誤提示,這是不對的,問題出在第一句判斷句的(x=0)中的“=”,該式子表達(dá)的意思是把0賦予x,因此無論前面如何改變x的值,執(zhí)行到第一句判斷句時(shí)x的值就會被改變?yōu)?,判斷的結(jié)果永遠(yuǎn)都是輸出錯(cuò)誤提示。
1.2 邏輯或運(yùn)算符“||”和邏輯與運(yùn)算符“&&”
邏輯運(yùn)算的結(jié)果為邏輯值,邏輯值只有兩個(gè)值:“真”和“假”,在C語言中用1表示“真”,用0表示“假”[2]。邏輯運(yùn)算符的運(yùn)算數(shù)一般為邏輯值,如果不是邏輯值的會自動(dòng)轉(zhuǎn)為邏輯值,轉(zhuǎn)換的規(guī)則是:0為邏輯假,非0為邏輯真。
邏輯或“||”:如果兩個(gè)運(yùn)算數(shù)都是假的,則結(jié)果是假的,否則結(jié)果為真;
邏輯與“&&”:如果兩個(gè)運(yùn)算數(shù)都是真的,則結(jié)果是真的,否則結(jié)果為假;
邏輯或“||”和邏輯與“&&”的表達(dá)式運(yùn)算規(guī)則
如果依靠死記硬背這些規(guī)則,不常用時(shí)是容易混亂出錯(cuò)的。為了方便記憶可以用一個(gè)生動(dòng)的比喻來幫忙,就是邏輯或“||”是一個(gè)“好好老師”而邏輯與“&&”則是一個(gè)“嚴(yán)格老師”。怎么解釋應(yīng)用呢?可以這樣看:“好好老師”(或“||”)的要求比較松,只要兩個(gè)數(shù)有一個(gè)是“真”的就可以通過,結(jié)果就是“真”的;而“嚴(yán)格老師”(與“&&”)比較嚴(yán)格要求只有兩個(gè)數(shù)都是“真”的才能通過,結(jié)果才是“真”的,如果有一個(gè)是“假”的就不能通過,結(jié)果就是“假”的。
除了上表的運(yùn)算規(guī)則還要注意邏輯運(yùn)算規(guī)律是:從左到右的運(yùn)算的?!昂煤美蠋煛保ɑ颉皘|”)在運(yùn)算時(shí)如果一直是“假”的就一直向左運(yùn)算,只要遇到“真”的就結(jié)束運(yùn)算結(jié)果為“真”或全部操作數(shù)運(yùn)算結(jié)束仍然沒有“真”結(jié)果就為“假”?!皣?yán)格老師”(與“&&”)在運(yùn)算時(shí)如果遇到“假”就結(jié)束運(yùn)算結(jié)果為“假”,只有一直遇到“真”的才能繼續(xù)運(yùn)算,直到所有操作數(shù)結(jié)束,結(jié)果為“真”。
這兩個(gè)運(yùn)算符在C語言中是很常被使用的,在使用過程中它們還分為前綴運(yùn)算和后綴運(yùn)算兩種[3]。它們只作用于變量,不能用于常量和表達(dá)式,如:1++,(a+b)++都是不對的,但是自增、自減的變量是可以出現(xiàn)在表達(dá)式中的,如:a=a+b++是可以的。
運(yùn)算中變量本身的自增與自減是很容易的,但是與之結(jié)合的表達(dá)式運(yùn)算就會出現(xiàn)無法抉擇的情況。
例子中的x、y的值都與原來預(yù)計(jì)中的不同的原因是:
在x=j+i++中,i++是后綴引用,是先將變量i的值引用到表達(dá)式中參加運(yùn)算后再自增,即x=j+i=1+1=2,i=i+1=2,而不是i=i+1=2,再x=j+i=1+2=3,注意:即使加上括號變?yōu)閤=j+(i++)運(yùn)行時(shí)也是一樣的。
在y=j+++i中,本意是要做前綴運(yùn)算++i的,但因與前面的算術(shù)運(yùn)算符+連在一起出現(xiàn)了混亂,是應(yīng)該運(yùn)算y=j+(++i)還是運(yùn)算y=(j++)+i。如果是y=j+(++i),表達(dá)式的結(jié)果就會是預(yù)想中i=i+1=2,y=j+i=1+2=3,但結(jié)果卻是y=2,應(yīng)該是運(yùn)算y=(j++)+i,自增的變量對象由i變成了j,j++也是后綴引用,因此最后的結(jié)果變?yōu)椋簓=j+i=1+1=2,j=j+1=2。在y=j+++i中變?yōu)檫\(yùn)算y=(j++)+i的原因是自增和自減的運(yùn)算優(yōu)先級高于算術(shù)運(yùn)算符,+++放在一起就要先運(yùn)算++再運(yùn)算+。
情況3:
在這個(gè)表達(dá)式中變量i的自增出現(xiàn)多次,使得運(yùn)算起來很復(fù)雜,這時(shí)要注意的是自增與自減運(yùn)算規(guī)律是:自右向左。j=(i++)+(i++)+i+(++i);執(zhí)行的運(yùn)行過程可以看成:
①從右邊的++i開始執(zhí)行,i=2;
②j=i+i+i+i,i++中的i的都是先參與表達(dá)式運(yùn)算再自增,j=2+2+2+2=8;
③先后執(zhí)行兩次i++,最后i的值變?yōu)?。
執(zhí)行的過程比較復(fù)雜,不易讀懂和判斷結(jié)果,而且在不同的編譯環(huán)境下運(yùn)行的結(jié)果也不一定是相同的,所以在表達(dá)式中同一個(gè)變量多次出現(xiàn)時(shí),不宜使用變量自增、自減運(yùn)算。
2 語句結(jié)束符“;”的問題
在C語言中每個(gè)語句的結(jié)束是以“;”為結(jié)束標(biāo)志的[4]。語句后如果多加了一個(gè)分號并不是錯(cuò)誤,可以將之看作是個(gè)不執(zhí)行任何操作的空語句,這時(shí)編譯系統(tǒng)是會發(fā)出警告提示的,提醒用戶注意并可以進(jìn)行修改。但是有些時(shí)候有些特殊位置加上分號系統(tǒng)是不會提示的有問題的,如
①if(x==0)printf("error?。躰");加個(gè)分號在條件后面if(x==0);printf("error!\n");沒有細(xì)看是不易發(fā)現(xiàn)的,但是這時(shí)執(zhí)行這個(gè)句子時(shí),無論x的值是否為0,都會輸出“error!”的語句。這次不是賦值“=”與“==”的問題,而是多出分號造成的問題。加了分號的句子應(yīng)該理解為:
如果在while(x++<10)后面加個(gè)“;”,那整個(gè)句子的執(zhí)行結(jié)果將不一樣,句子原來的結(jié)果是輸出123456789,而多了分號后輸出的結(jié)果就變?yōu)檩敵鲎詈髕的值:10。僅因?yàn)橐粋€(gè)小小的“;”影響了整個(gè)程序的效果,所以分號的使用需要注意:少了不行,多了也不行。
3 “else”問題
在C語言中else是必須和if一起配對使用的,不可以獨(dú)立使用,它的后面沒有括號即沒有條件,條件相當(dāng)于默認(rèn)是與if小括號的條件相反的所有條件[1]。
if... else 配對原則是:缺省{ }時(shí),else總是和它上面離它最近的未配對的if配對。
上面例子中第一個(gè)else就與前面的if配對,第二個(gè)else就不能再與該if配對了,前面沒有其他的if可以與它配對。第二個(gè)else就被獨(dú)立出來單獨(dú)使用,else本身是沒有條件的,要否定與其配對的if的條件來做其本身的條件,這樣的else就沒有辦法真正的執(zhí)行。要正確的完成上面的程序就需要給第二個(gè)else配個(gè)if,如:
補(bǔ)充完整語句后,最好能夠使用縮進(jìn)將相關(guān)聯(lián)的語句進(jìn)行對齊,這樣便于讀程序,可以看出第一個(gè)else是與第一個(gè)if配對,它是否定x>80這個(gè)條件的即它的條件是小于等于80的執(zhí)行后面的語句。第二個(gè)else是與第二個(gè)if配對的,它的條件是小于等于60執(zhí)行后面的語句。如果這樣還是不易看懂,可以再加上大括號變?yōu)椋?/p>
這樣就比較清晰明確了。else的配對錯(cuò)誤問題不僅是上面這種情況,還有很多,主要是能掌握if...else配對原則才能判斷出正確的配對情況。
總之,C語言中的靈活特點(diǎn),使得學(xué)習(xí)時(shí)要靈活運(yùn)用規(guī)則來掌握各種特殊情況的處理辦法。掌握好C語言為將來多方面的程序設(shè)計(jì)學(xué)習(xí)之路打下基礎(chǔ)。文章中實(shí)例的運(yùn)算結(jié)果是在Turbo C環(huán)境下得出,不同的系統(tǒng)環(huán)境結(jié)果可能有些不同,請讀者見諒。
[參考文獻(xiàn)]
[1]熊錫義.C語言程序設(shè)計(jì)案例教程[M].大連:大連理工大學(xué)出版社,2009.5.
[2]龔民.C語言程序設(shè)計(jì)實(shí)用教程[M].青島:中國海洋大學(xué)出版社,2011.8.
[3]許崇,王秀紅,王洪信.C程序設(shè)計(jì)語言中兩個(gè)疑難問題的探討[J].科技與生活,2010(4):23.
[4]雷萌,趙亞妮.C語言疑惑經(jīng)驗(yàn)談[J].軟件導(dǎo)刊,2011(3):80-82.