初學者常遇到:程式能編譯執行,輸入資料後卻完全沒有輸出結果,甚至直接結束。
#include <stdio.h>
int main() {
float x;
printf("請輸入一個數字: ");
scanf("%f", x); // ❌ 錯誤:缺少取址運算子 &
if (x > 0) printf("正數\n");
else if (x < 0) printf("負數\n");
else printf("零\n");
return 0;
}
scanf("%f", x) 將變數 x 的值 (未初始化的亂碼) 當作記憶體位址傳遞給 scanf。x 根本沒被更新,後續判斷使用的是垃圾值。scanf("%f", &x); // ✅ 正確:傳遞 x 的記憶體位址
變數 x 在記憶體中佔據 4 bytes (float)
位址: 0x7ffeefbff5a0 (假設)
值: 未初始化 (垃圾值)
scanf("%f", &x) → 將輸入的數字寫入 0x7ffeefbff5a0
scanf("%f", x) → 嘗試寫入「垃圾值」當作位址 → 崩潰或靜默錯誤
現代編譯器 (GCC/Clang/MSVC) 會發出警告:
warning: format '%f' expects argument of type 'float *', but argument 2 has type 'float' [-Wformat=]
務必開啟警告並視為錯誤 (-Wall -Werror 或 VS 專案屬性設定),養成「零警告」習慣。
| 錯誤 | 正確 | 說明 |
|---|---|---|
scanf("%d", n); | scanf("%d", &n); | 整數同樣需要 & |
scanf("%s", str); (char str[20]) | scanf("%s", str); | 陣列名稱本身即為位址,**不需** & |
scanf("%c", &ch); 吃掉換行符 | scanf(" %c", &ch); | 格式字串前加空白跳過空白字元 |
| 未檢查回傳值 | if (scanf("%d", &n) != 1) ... | scanf 回傳成功轉換的項目數,可偵測輸入失敗 |