日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C符号陷阱

發(fā)布時間:2025/3/15 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C符号陷阱 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

???? 術(shù)語“符號”指的是程序的一個基本組成單元,其作用相當(dāng)于一個句子中的單詞。在程序中,符號就是程序的一個基本信息單元。而組成符號的字符序列就不同,同一組字符序列在某個上下文環(huán)境中屬于一個符號,而另一個上下問環(huán)境中可能屬于完成不用的另一個符號。

1.1? =不同于==

???? 在C語言中符號=作為賦值運(yùn)算,符號==作為比較,一般而言賦值運(yùn)算相對于比較運(yùn)算出現(xiàn)得更頻繁,因此字符較少的符號=就被賦予了更常用的含義——賦值操作。此外,在C語言中賦值符號被作為一種操作符對待,因而重復(fù)進(jìn)行賦值操作(如a=b=c)可以很容易地書寫,并且賦值操作還可以被嵌入到更大的表達(dá)式中。

???? 但是,這種使用上的便利性可能導(dǎo)致一個潛在的問題:當(dāng)程序員本意是在作比較運(yùn)算時,卻可能無意中誤寫成賦值運(yùn)算。比如下例,該語句本意似乎是要檢查 x 是否等于 y :

if (x = y)break;

而實(shí)際上是將 y 的值賦給了 x ,然后檢查該值是否為零。我們再來看看下面的例子:

while (c = ‘ ’ || c == ‘\t’ || c== ‘\n’)c = getc (f);

???? 該程序的本意是跳過文件中的空格符、制表符和換行符,但是由于程序員在比較字符 ' ' 和變量 c 時,誤將比較運(yùn)算符 == 寫成了賦值運(yùn)算符 = 。因?yàn)橘x值運(yùn)算符 = 的優(yōu)先級要低于邏輯運(yùn)算符 || ,因此實(shí)際上是將以下表達(dá)式的值賦給了 c :

' ' || c == ‘\t’ || c== ‘\n’

???? 因?yàn)?' ' 不等于零(' ' 的ASCII碼值為32),那么無論變量 c 此前為何值,上述表達(dá)式的值都是1,因此循環(huán)將一直進(jìn)行下去直到整個文件結(jié)束。

???? 某些C編譯器在發(fā)現(xiàn)形如e1 = e2的表達(dá)式出現(xiàn)在循環(huán)語句的條件判斷部分時,會給出警告消息以提醒程序員。當(dāng)確實(shí)需要對變量進(jìn)行賦值并檢查該變量的新植是否為0時,為了避免來自該類編譯器的警告,我們不應(yīng)該關(guān)閉警告選項(xiàng),而應(yīng)該顯示地進(jìn)行比較。也就是說:

if (x = y)foo();

應(yīng)該寫作:

if ((x = y) != 0)foo();

???? 這種寫法也使得代碼的意圖一目了然。

???? 前面一直談的是把比較運(yùn)算誤寫成賦值運(yùn)算的情形,另一方面,如果把賦值運(yùn)算誤寫成比較運(yùn)算,同樣會造成混淆:

if ((filedesc == open(argv[i],0)) < 0)error();

???? 在本例中,代碼的本意是將函數(shù)open的返回值存儲在變量filedesc中,然后通過比較變量filedesc是否小于0來檢查函數(shù)open是否執(zhí)行成功。但是此處的==本應(yīng)是 = ,按照上面的代碼實(shí)際進(jìn)行的是比較函數(shù)open的返回值與變量filedesc,然后檢查比較的結(jié)果是否小于0。顯然比較的結(jié)果要么是0,要么是1,永遠(yuǎn)不可能小于0,所以函數(shù)error()將沒有機(jī)會被調(diào)用。

?

1.2? “貪心法”

???? C語言對于運(yùn)算符號有一個簡單的規(guī)則:每一個符號應(yīng)該包含盡可能多的字符,也就是說,編譯器將程序分解成符號的方法是,從左到右一個字符一個字符地讀入,如果該字符可能組成一個符號,那么再讀入下一個字符,判斷已經(jīng)讀入的兩個字符組成的字符串是否可能是一個符號的組成部分,如果可能,繼續(xù)讀入下一個字符,重復(fù)上述判斷,直到讀入的字符組成的字符串已不再可能組成一個有意義的符號。這個處理策略有時被稱為“貪心法”。

???? 下面的表達(dá)式

a---b

與表達(dá)式

a-- - b

的含義相同,而與

a - --b

的含義不同。

???? 根據(jù)代碼中注釋的意思,下面的語句的本意似乎是用x除以p所指向的值,把所得的商再賦給y:

y = x/*p /* p指向除數(shù) */

而實(shí)際上 /* 被編譯器理解為一段代碼注釋的開始。應(yīng)該更清楚點(diǎn),寫作:

y = x / (*p) /* p指向除數(shù) */

這樣才得到的實(shí)際效果才是語句注釋所表示的原意。

?

練習(xí):1-1.? a+++++b 的含義是什么?

???? 上式我們想到有意義的表達(dá)就是:(a++) + (++b)

???? 可是,我們根據(jù)“貪心法”規(guī)則,上式應(yīng)該被分解為:

((a++)++) + b

但是,a++ 的結(jié)果不能作為左值,因此編譯器不會接受 a++ 作為后面的 ++ 運(yùn)算符的操作數(shù),故這樣的式子是沒意義的。

?

?

參考書籍:C陷阱與缺陷

轉(zhuǎn)載于:https://www.cnblogs.com/iuices/archive/2011/11/20/2256453.html

總結(jié)

以上是生活随笔為你收集整理的C符号陷阱的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。