27. 執行下列 C 語言程式後產生的輸出為何?
#include <stdio.h> 
main() { 
int a= 2, b = 5; 
a *= a-- * --b; 
printf("%d\n", a); 
 
(A) 4
(B) 8
(C) 15
(D) 19

答案:登入後查看
統計: A(27), B(161), C(117), D(15), E(0) #718122

詳解 (共 8 筆)

#4112185

a *= a-- * --b;

會先執行完 a-- * --b (我先假設有另一個變數 c = a-- * --b,方便區分),才計算 a *= c

c = a-- * --b

   = 2*4

   = 8

算出 c 以後執行 a-- ,此時 a = 1

接著計算a * = c,可寫成a = a * c

a = 1 * 8 = 8

所以編譯器才會算出8

先說結論:這題考選部出題有誤,給了錯誤解答


再詳細探討編譯器的行為的話

其實 a *= a-- * --b; 的先後順序是未定義行為

因為無法判斷編譯器如何執行帶有 *= 與 a-- 同時出現時的先後順序

可能每個編譯器算出來的結果都不同

應該會有兩種情況


情況一:

a *= a-- * --b;可寫成 a = a * (a-- * --b);

假設編譯器將 a 都以 2 代入,一次執行完 a * (a-- * --b) (此時左右兩個 a 的值皆為2)

a = 2 * (2 * 4) =16 (注意,這裡的 16 先還不要存回變數 a )

在計算的過程中才執行 a--,執行完以後 a = 1

但其實 a-- 並不影響最終 a 的值

因為 a-- 之後馬上又被計算出來的 16 給存回 a 這個變數

也就是先把 a = 2 代入 a * (a-- * --b) = 2 * (2 * 4) 後才執行 a--,最後再算出 a = 2 * (2 * 4) = 16 的答案

所以最後 a = 16


情況二:

假設編譯器是分開計算的

先將 a-- * --b 計算出來,接著執行 a--,最後才計算 a *= c (一樣假設 c = a-- * --b,方便區分)

先執行 c = a-- * --b = 2 * 4 = 8,接著執行 a--,此時 a = 1, c = 8

再執行a *= c,也就是 a = a * c = 1 * 8 = 8

所以最後 a = 8


不管編譯器用哪種算法都不可能出現 15 這個答案

這題有可能出現的答案只有 8 或 16 


以上是我個人對編譯器粗淺的理解,如果有說錯的地方請見諒,謝謝

2
0
#2735937

字尾遞減(a--) 優先級高於  *

a=a*a--*--b

a=1*2*4=8

複製到ideone實跑就是8 


2
0
#1358511
可是實際寫成程式跑出8耶,求解?
2
0
#3282484

答案為 (B) 8 吧

5c89f1b83e2bb.jpg#s-367,233

1
0
#4122644
說實話,一樓的算法我完全看不懂,到底是怎...
(共 127 字,隱藏中)
前往觀看
0
0
#3282764
原本答案為C,修改為B
(共 13 字,隱藏中)
前往觀看
0
0
#3292284
可是考選部標準答案為C
(共 13 字,隱藏中)
前往觀看
0
0
#1299056
a=a*a--*--b
a=2*2--*4 = 16-1 = 15
-2
6

私人筆記 (共 2 筆)

私人筆記#3556677
未解鎖
a--為後置 整行執行完才++ 就跟f...
(共 42 字,隱藏中)
前往觀看
0
0
私人筆記#1327824
未解鎖
a *= a-- * --b a = ...

(共 167 字,隱藏中)
前往觀看
0
0