C之 ++ 和 -- 操作符
++ 和 -- 操作符對應兩條匯編指令,前置時:變量自增(減)1後取變量值;後置時:取變量值後變量自增(減)1。
下來我們來看個示例代碼,代碼如下:
#include <stdio.h> int main() { int i = 0; int r = 0; r = (i++) + (i++) + (i++); printf("i = %d\n", i); printf("r = %d\n", r); r = (++i) + (++i) + (++i); printf("i = %d\n", i); printf("r = %d\n", r); return 0; }
我們分析第8行,i++執行3次,r = 0 + 1 + 2 = 3; i = 3; 第 13 行 r = 4 + 5 + 6 = 15; i = 6;我們來看看 gcc 下編譯的結果是多少
我們看到最後的 r 打印的是 16,跟我們分析的不一樣。那麽我就直接告訴大家答案了,這塊需要去反匯編看看代碼是怎麽執行的。通過查看匯編代碼,我們發現在 gcc 中,它先是自增兩次然後相加,再次自增一次,再加上6,結果就是16了。有興趣的同學可以自己去反匯編,看看代碼是怎樣執行的。我們再來看看 BCC 這款編譯器執行的結果是怎樣的
我們發現最後一個 r 和我們分析的一樣,但是第一個 r 為0,這是怎麽回事呢?還是得通過反匯編代碼來看,它是這樣執行的,先把 0 拿出了加三次,再次自增 3 次。所以第一個 r 為0,而 i 為3。
在 C 語言中只規定了 ++ 和 -- 對應指令的相對執行次序;++ 和 -- 對應的匯編指令不一定連續執行;在混合運算中,++ 和 -- 的匯編指令可能會被打斷執行,換句話說,++ 和 -- 參與混合運算的結果是不確定的。
我們會在一些筆試題中遇到這樣一些題目:1、++i+++i+++i;2、a+++b;那麽我們在遇到這些題目時該怎樣去解答呢?在 C 語言中它的處理是貪心法,即:a> 編譯器處理的每個符號盡可能多的包含字符;b> 編譯器以從左向右的順序一個一個盡可能多的讀入字符;c> 當讀入的字符不可能和已讀入的字符組成合法符號為止。
我門下來就來分析個示例代碼,代碼如下:
#include <stdio.h> int main() { int i = 0; int j = ++i+++i+++i; int a = 1; int b = 4; int c = a+++b; printf("i = %d\n", i); printf("j = %d\n", j); printf("a = %d\n", a); printf("b = %d\n", b); printf("c = %d\n", c); return 0; }
我們來分析下,第 6 行相當於 j = ++i++ ==> 1++,這樣會出錯,因為1++不是個合法的表達式。第10行相當於 c = a+++b ==> c = 1 + 4 ==> c = 5;這時 a = 2;
我們編譯的時候第6行出現錯誤
那麽我們在下面加上一句 1++,看看打印的錯誤提示是否和上面的一樣呢
大家看到兩句錯誤提示一樣,證明我們的分析是對的,我們屏蔽後再次執行
我們看到 a = 2, c = 5 和我們分析的一樣。那麽我們在平時的書寫中可以加上空格,空格可以作為 C 語言中的一個完整符號的休止符,編譯器讀入空格後立即對之前讀入的符號進行處理。同時加入空格也可以增強程序的可讀性。
通過本次 ++ 和 -- 操作符的學習,我們總結如下:1、++ 和 -- 操作符在混合運算中的行為可能不同;2、編譯器通過貪心法處理表達式中的字表達式;3、空格可以作為 C 語言中一個完整符號的休止符,編譯器讀入空格後立即對之前讀入的符號進行處理。後面我們會繼續對 C 語言的學習。
歡迎大家一起來學習 C 語言,可以加我QQ:243343083。
C之 ++ 和 -- 操作符