int a = 2, b = 7, c = 5;
switch (a > 0) { // 表達式值為 1 (true)
case 1:
switch (b < 0) { // b<0 為 0 (false)
case 1: printf("@"); break;
case 2: printf("!"); break;
} // 內層無 case 0,直接退出
case 0: // 外層 case 1 無 break,貫穿到此
switch (c == 5) { // 為 1 (true)
case 1: printf("*"); break;
case 2: printf("#"); break;
default: printf("#"); break;
}
default: printf("&"); // 同理貫穿
}
輸出:*&
a>0 為真(1),進入 case 1。b<0 為假(0),無匹配 case 0,內層 switch 結束。case 1 無 break,貫穿 到 case 0。c==5 為真(1),匹配 case 1 輸出 *,有 break 跳出內層 switch。case 0 也無 break,繼續貫穿到 default 輸出 &。教訓:永遠在 case 末尾加 break,或用 [[fallthrough]] (C++17/C23) 顯式標註故意貫穿。
int i = 0; // 全局變量
int fun1(int i) { // 參數 i 遮蔽全局 i
i = (i % i) * (i * i) / (2 * i) + 4; // 注意:i=0 時除零未定義!此處調用傳入非零
printf("i = %d\n", i);
return i;
}
int fun2(int i) { // 參數 i 遮蔽全局/外層 i
i = i <= 2 ? 5 : 0;
return i; // 返回值未被接收
}
int main() {
int i = 5; // 局部變量 i
fun2(i / 2); printf("i = %d\n", i); // 1
fun2(i = i / 2); printf("i = %d\n", i); // 2
fun2(i / 2); printf("i = %d\n", i); // 3
fun1(i / 2); printf("i = %d\n", i); // 4
return 0;
}
輸出序列:
i = 5 i = 2 i = 2 i = 4 i = 2
main 中 i=5。打印 5。fun2(i/2) → fun2(2)。形參 i=2,i<=2 為真,形參改為 5 返回。實參未變(值傳遞)。打印 main 的 i 仍為 5? 待會兒... 等等,第一次調用是 fun2(i/2),不修改 main 的 i,所以第一次打印應為 5。但題目給出的答案第一個是 5? 讓我們重新核對題目給出的答案:5,2,2,4,2。 printf 在 fun2(i/2) 之後,main 的 i 仍是 5,輸出 5。fun2(i = i/2):先計算 i/2=2,賦值給 main 的 i (現為 2),再傳入 fun2。fun2 內部修改形參無影響。打印 main 的 i 為 2。fun2(i/2):main 的 i 為 2,傳入 1。打印 main 的 i 仍為 2。fun1(i/2):傳入 1。fun1 內部:i=1。計算 (1%1)*(1*1)/(2*1)+4 = 0*1/2+4 = 4。打印 fun1 內部 i=4。返回。main 的 i 不變 (2)。打印 main 的 i 為 2。5,2,2,4,2,似乎包含了 fun1 內部的 printf 輸出 4 作為第四個輸出? 題目代碼中 fun1 有 printf("i = %d\n", i);,main 中調用後也有 printf。實際輸出應為 6 行? 題目簡化了,只列出關鍵值。核心知識點已清晰。i = i/2 的值是賦值後的 i,可作為函數實參。fun1 中 i % i 若 i=0 觸發未定義行為,實際調用傳入 1/2 避開了此坑。