程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C >> 關於C >> 玩兒轉C語言:符號序列

玩兒轉C語言:符號序列

編輯:關於C

     編譯原理中講到程序構造的一般過程是:詞法分析、語法分析、語義分析、中間代碼生成、代碼優化和目標代碼生成。詞法分析對應的就是C語言中的“單詞”(也稱“符號”),指的是程序的一個基本組成單元,每個符號都有自己固定的字符序列,但是同一個字符序列可能屬於不同的符號。

例如:字符序列“->”,有可能代表的是->運算符,也有可能代表字符串“->”,這就需要根據上下文環境判斷。

1、C語言中符號之間的空白(空格、制表符或換行符)都被忽略  


if(1<x)

if
(
1
<
x
)
        這兩條語句是等效的,注意這裡指的是“符號之間”的空白,不是“符號之內”,如果把“if”寫成“i f”是不行的,"if"在C語言內部是一個固定的符號,是可以識別的有效“單詞”,而“i f”卻不是,可以拿英文句子來類比分析。“I am the best!”是一個有效語句,是因為在詞法分析時各個單詞都是有效單詞;如果寫成“I    am  the       best!”,仍然有效;但是“I am the b est !”無效,因為“b est”在系統庫中無法找到匹配的單詞,道理相同。
2、C語言中符號之內不能有空白(空格、制表符或換行符)

        編譯器區分各個符號的終極原則就是“空白”(還有其他原則,例如貪心法),如果符號之內有空白,編譯器只能(也是必須)把它們解釋成“兩個或多個符號”,如果沒有空白,也可能解釋成多個符號,這時貪心法在起作用。例如:++是一個“自增運算符”,+ + 就是兩個“加法運算符”,+++雖然沒有空白,也只能解釋成“自增運算符+加法運算符”,因為貪心法在作怪。

3、“符號之間”和“符號之內”的討論,有什麼用處?

        我們編寫程序,首先是給人讀懂,其次是給計算機(也可認為編譯器)讀懂,兩者缺一不可。如果“人”和“計算機”對同一個事物的理解出現偏差,那運行結果就不可預料了,而今天的討論就是為了讓我們更加“懂計算機”,理解“計算機”的思維方式,在“人”讀懂的基礎上,讓“計算機”也能讀懂,甚至必要時以“計算機”讀懂為根本方針。

        詞法分析中的“貪心法”:編譯器在對符號進行分解時,必須對某個“連續字符串”進行順序分析(不連續的字符串,肯定不屬於同一個“符號”,直接截斷並對每個片段單獨用貪心法分析),確定由幾個符號(單詞)組成。確定符號的過程中,編譯器假設每個符號包含盡可能多的字符(字母),即:從字符偏移0開始依次讀取字符串,如果加上下一個字符還能組成一個有效的符號就加上它,持續添加直到加上某個字符後,就不再是一個有效符號了,那麼這個字符前面的從偏移0開始的字符串,就是一個有效的“符號”;繼續修改偏移0到這個字符,持續上述過程知道本行結束。

       理解了“貪心法”,我們在程序書寫上就應該盡量照顧計算機的思想,而不是隨便寫一通。例如:

result = num/*p;
        對這行代碼,計算機用貪心法分析符號有6個“result、=、num、/*、p、;”,而我們的理解是“result 、=、num、/、*p、;”。本來想寫一個除法表達式,num除以指針p指向的內容,可是計算機理解成了“result = num”剩下的是注釋,顯然不是我們想要的。如何切斷貪心法對"/*"的連接呢?根據上面的討論,我們用“空格”,寫出這樣:
result = num/ *p;
        當增加一個空格後,貪心法再次分析到“/”的時候,由於後邊緊跟空格不再是連續字符串,所以無條件截斷,這樣就可以防止上面的情況發生。還可以用括號進行顯式指定:
result = num / (*p) ;
        這一次既對代碼進行了手動空格分割,便於計算機理解,又添加了括號,增加了代碼的可讀性。真正高質量的代碼就是這樣,計算機閱讀沒有二義性,人閱讀也沒有二義性。所以代碼中,要善於利用空格和括號,提高規范性提升代碼質量,防止歧義發生。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved