自增,自減操作符的編譯過程

2021-09-28 17:20:50 字數 2127 閱讀 8164

詞法分析,是指編譯器把c程式中的字元處理為乙個個c語言中的符號的過程。c語言中的操作符有單字元的(例如=,-,+),也有兩個字元的(例如:++,--),還有更多字元的(例如型別轉換操作符)。因為c語言允許兩個操作符之間沒有空格(例如v =+ d,其中=+為兩個操作符),因此,某些字元在一起可以組成多種不同情況的操作符。例如:

++bbb;

理論上,++除了可以視為前自增操作符,也可以視為兩個正號操作符,等效於:

+(+bbb);

這個結果在語法上也是正確的。那麼,c編譯器是如何處理這種情況的呢?事實上,c編譯器在識別**時,遵守一種稱為「貪婪法」的處理方式:「如果編譯器的輸入流截止至某個字元前,所有的字元都已經被解析為乙個個完整的符號,那麼,下乙個符號將包括從該字元之後可能組成乙個符號最長的字串」。其中,所謂的「編譯器的輸入流」就是指程式**。

需要注意的是,詞法分析與語法分析屬於兩個不同的階段。再詞法分析之後,才會開始語法分析。c編譯器作詞法分析時不會考慮語法,不會嘗試去做語法上正確的解析,只會機械地按一定規則在符號層面上處理程式**。例如:

+++++++b;

按照貪婪法,分析的結果等效於:

++ ++ ++ + b;

再進行語法分析,自增操作符與加法操作符結合性為從右到左,分析結果等效於:

++ (++(++(+b)));

這在語法上是錯誤的,編譯會提示自增操作符缺少左值(1-value)。但是,如果從語法上考慮,這個語句中的字元也是可以組成正確的語句的。例如:把所有加號都視為正號操作符:

+ + + + + + +b;

但是,這樣做容易導致二義性。例如,語法正確的分析結果還有:

+ + + + + (++b);

前5個加號為正號操作符,第6個和第7個組成自增操作符。這樣,編譯器會產生錯亂,不知該採取哪種解析結果。因此,詞法分析時,編譯器不會考慮語法。

請看以下**:

01 #include

02 int main(void)

03 {

04 int a = 1;

05 int b = 1;

0607 b = +++a; /錯誤/

08 b = + ++a; /正確/

09 b = ++ +a; /錯誤/

10 b = + + +a; /正確/

1112 b = -++a; /正確/

13 b = -±a; /正確/

1415 b = a++++b; /錯誤/

16 b = a+++ +b; /正確/

1718 return 0;

19 }

【**解析】

在上述程式中,從第7~10行,語句的字元完全一樣,只是其中三個加號之間的空格數有所區別。

第7行中,三個加號連在一起,按照貪婪法,前兩個加號被解析為自增操作符,第3個加號解析為正號操作符。解析效果等效於:

b = ++ (+ a);

在語法上,由於自增操作符與正號操作符優先順序相同,因此,按照從右到左的結合性,先執行+a,再對執行的結果做自增。由於+a的值不能被賦值,因此,該語句是錯誤的。提示資訊為:自增操作符缺少左值。

第10行中,每兩個加號之間都有乙個空格,因此,三個加號都被解析為正號操作符。按照從右到左的順序結合,該語句等效於:

b = + ( + ( +a) );

第12行與第13行語句的詞法解析比較簡單,都能得到正確的結果,分別等效於:

b = - ( ++a );

b = - ( + ( -a ) );

第15行中,詞法分析的等效結果為:

b = (a++) ++ b;

這個語句在語法上是錯誤的,兩個自增操作符都是後自增操作符。第乙個後自增操作符的運算元為變數a,第二個後自增操作符的運算元為a++的值。因為a++不能為左值,是針對第二個操作符而發的。由於(a++) ++是乙個完整的表示式,而b也是乙個完整的表示式,在它們之間必須有操作符或者分號,因此,編譯器還會報告乙個錯誤:b之前缺少分號。

第16行中,前3個分號之間緊挨在一起,在第4個加號之間有乙個空格。該語句將被解析為:

b = (a++) + (+b); /*第16行的等效效果*/

自增 和自減 操作符

自增操作符和自減操作符經常要在我們自定義的類型別中使用到,而使用時經常會出現問題。現把自己在學習的過程中的 拿出來看一下,也是c primer中的例子如下 ifndef check ptr define check ptr include using namespace std class chec...

關於自增自減操作符

c c 中自增自減運算子相信是不少人的乙個困擾,這個問題也一直困擾著我,今天再次翻開書本來看了看,有了些新的體會,所以在這裡記錄下來,同時也與那些像我一樣被困擾的人分享,程式設計大牛可以繞道了,或者有什麼不對的地方請大牛們指正。以 為例,如下程式輸出結果是什麼 int a 0,j 1 a j cou...

自增和自減操作符

毫無疑問,自增 和自減 操作符為物件加1或減1操作提供了方便簡短的實現方式。程式設計中的宗旨 簡潔即美 它們有前置和後置兩種使用形式 int i 0,j j i j 1,i 1 prefix yields incremented value j i j 1,i 2 postfix yields un...