經典新手代碼錯誤診斷與修正
原代碼錯誤
#include <stdio.h>
// 缺少 #include <math.h> → sqrt() 隱式聲明,返回 int,導致精度丟失/錯誤
main() { // 非標準,應 int main(void)
float a,b,c,d,x1,x2;
printf("input a,b,c:\n");
scanf("%f%f%f\n", &a,&b,&c); // 格式串末尾 \n 導致掃描阻塞等待非空白字符
if ((b*b-4*a*c)<0)
printf("無解\n");
else
d=sqrt(b*b-4*a*c); // 隱式聲明 sqrt 返回 int
x1=(-b+d)/(2*a);
x2=(-b-d)/(2*a);
printf("%f%f\n",x1,x2); // 缺分隔符/換行
}
三大核心錯誤
| 錯誤 | 後果 | 修正 |
缺 #include <math.h> | sqrt 隱式聲明為 int sqrt(),實際返回 double 截斷嚴重 | **必須包含 <math.h>**,編譯鏈接時加 -lm (GCC/Clang) |
scanf("%f%f%f\n", ...) | \n 匹配任意空白,導致程序掛起等待非空白輸入 | scanf("%f %f %f", ...) 或 scanf("%f%f%f", ...),**不要在格式串末尾放空白** |
printf("%f%f\n", x1, x2) | 輸出粘連如 1.0000002.000000 無法辨識 | printf("x1=%f, x2=%f\n", x1, x2) 或 printf("%f %f\n", x1, x2) |
標準修正版
#include <stdio.h>
#include <math.h>
int main(void) {
double a, b, c; // 用 double 提高精度
printf("輸入 a b c (空格分隔): ");
if (scanf("%lf %lf %lf", &a, &b, &c) != 3) {
printf("輸入格式錯誤\n"); return 1;
}
double disc = b*b - 4*a*c;
if (disc < 0) {
printf("無實數解 (判別式 = %.2f)\n", disc);
} else if (disc == 0) {
double x = -b / (2*a);
printf("唯一解: x = %.4f\n", x);
} else {
double sqrt_disc = sqrt(disc);
double x1 = (-b + sqrt_disc) / (2*a);
double x2 = (-b - sqrt_disc) / (2*a);
printf("兩解: x1 = %.4f, x2 = %.4f\n", x1, x2);
}
return 0;
}
編譯命令 (GCC/Clang)
gcc -std=c11 -Wall -Wextra -o quadratic quadratic.c -lm
# -lm 鏈接數學庫 (libm),math.h 函數定義在 libm 中
新手避坑清單
- 用
sqrt, sin, pow 等 **必須 #include <math.h> 並鏈接 -lm**。
scanf 格式串**不要以空白字符結尾** (\n, , \t)。
printf **必須加分隔符/換行/標籤**,否則輸出不可讀。
- 浮點運算優先用
double,float 精度僅 ~7 位有效數字。
- 判別式比較
== 0 存在浮點誤差,工程上用 fabs(disc) < 1e-9。
- 編譯**務必開啟警告**
-Wall -Wextra -Werror,隱式聲明會直接報錯。