C語言中的 ++x || ++y && z++ 是如何執行的?

測試例題

#include <stdio.h>

void main() {
    int x = 2, y = 2, z = 0, a;
    a = ++x || ++y && z++;
    printf("%d,%d,%d", x, y, z);
}

運行結果

3,2,0

問題本質
a+b && b*c

你看這道表達式,你說下它的求值順序,我猜你肯定會說:先算乘法,再算加法,最後算&&運算

而事實上,計算機在執行代碼的時候並不是這樣執行的,你想啊,計算機就是一個機器,它哪裏知道,哪一個表達式是要先計算的

所以在計算機執行代碼時,所有表達式的求值都是從左向右運算的

那你可能會問,那優先級是幹嘛的,不就是區分先執行那一個後執行哪一個的嘛?

還真不是,由於表達式有多種運算,不同的結合順序可能得出不同結果甚至出現錯誤運算錯誤

所以必須按一定順序進行結合,才能保證運算的合理性和結果的正確性、唯一性

你可以把優先級想象成誰跟誰在一塊,而不是優先級最高的最先計算

上邊的那個式子,在程序執行中,會被處理成等價的語句

( a+b) && (b*c)

它是怎麼執行的呢?剛纔說了,由於計算機是死腦筋,只會從左向右計算表達式的值,這是規定(就是這麼設計的)

所以:

第一步:先執行&&運算,因爲當前的表達式是 (…) &&(…)

第二步:在執行時發現&&的左邊有一個括號,那就先算括號裏的子表達式的值,a+b

第三步:然後計算右邊的括號的子表達式的值,也就是b*c

第四步:當執行完 第二步 和 第三步,運算兩邊的子表達式值就計算出來了,此時,&&運算就可以執行了

因此,我們可以都得到一個結論:優先級與求值順序無關。如a+b && b*c,雖然 * 優先級最高,但這個表達式求值順序是從左到右

而這道題,a = ++x || ++y && z++; 其實是一樣的,雖然&&運算符的優先級大於||運算符,但這並不意味着要先執行&&運算,因爲計算機它也不知道哪個表達式先執行,它只會從左向右依次運算值

計算機在運行時就根據優先級的結合,處理爲等價的語句,a =( (++x) || (++y && z++) );

由於計算機是死腦筋,表達式求值,從左向右進行

第一步:先計算=這個賦值運算,但是,發現右邊是一個表達式

第二步:計算機先停下來賦值運算,轉去計算右邊的複合表達式( (++x) || (++y && z++) )

第三步:此時又發現這是一個||運算,又分爲了左右兩邊兩個子表達式,怎麼辦,我先計算子表達式的值

第四步:計算(++x),咦,我發現++x後,這個表達式的值是3,在C語言中,非0即真,並且這是一個或運算,有一得一,後邊的表達式我就不用算了,偷個懶,計算機也很累的

第五步:||運算後的表達式值爲1,將 ( (++x) || (++y && z++) ) 表達式的值1賦值給變量a,這樣就完成了這條語句的執行

注意:我們犯的錯誤就是,主觀的認爲,我們人類怎麼計算,計算機就是怎麼計算,我們沒有考慮計算機的感受,它看不懂這麼複雜的表達式

只能做一些簡單的重複性工作,別的不會,從左向右一個一個算,這我倒是會的,那我就這麼來,而優先級說白了就是給這個表達式劃分括號的

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章