出錯特徵:程序執行流程出乎意料,結果不正確。c++
出錯樣例:算法
for (int i = 0; i < n; i++) { if (i = n) printf("%d\n", i); else printf("%d ", i); }
治療方法:剁手。多剁兩次就記住了。編程
出錯特徵:WA到死。數組
出錯樣例:函數
double a = 1 / 3 * 3; double b = 1; if (a == b) { printf("Yes"); }
治療方法:測試
const double eps = 1e-5; double a = 1 / 3 * 3; double b = 1; if (abs(a - b) < eps) { printf("Yes"); }
注意點:eps到底取多少? 通常在1e-5到1e-8之間。有些題目卡eps。(就是莫名其妙的一個wa一個ac)設計
出錯特徵:Output Limit Error 或 WA 或 RE 或 TE 或 機器爆炸。指針
出錯樣例:code
題目:計算a+b。ci
輸入:t組數據,每組測試數據包含兩個數a,b。
輸出:對於沒組數據,輸出a+b的值。每兩組輸出之間換行隔開
#include <cstdio> bool isFirst, t; int a, b; int main() { isFirst = true; scanf("%d", &t); while (t--) { scanf("%d%d", &a, &b); if (isFirst) { isFirst = false; } else { puts(""); } printf("%d\n", a + b); } return 0; }
數據: 3 1 2 2 3 3 4
治療方法:先睡一覺。寫出這種代碼,你必定是太累了。
int a = (10*3/2 + 10)/3
)由於被計算機表示浮點數的方式所限制,CPU在進行浮點數計算時會出現偏差。如執行0.1 + 0.2 == 0.3
結果每每爲false
,在四則運算中,加減法對精度的影響較小,而乘法對精度的影響更大,除法的對精度的影響最大。因此,在設計算法時,爲了提升最終結果的精度,要儘可能減小計算的數量,尤爲是乘法和除法的數量。
浮點數與浮點數之間不能直接比較,要引入一個eps
常量。eps
是epsilon(εε)的簡寫,在數學中每每表明任意小的量。在對浮點數進行大小比較時,若是他們的差的絕對值小於這個量,那麼咱們就認爲他們是相等的,從而避免了浮點數精度偏差對浮點數比較的影響。eps在大部分題目時取1e-8
就夠了,但要根據題目實際的內容進行調整。
// sgn返回x通過eps處理的符號,負數返回-1,正數返回1,x的絕對值若是足夠小,就返回0。 const double eps = 1e-8; int sgn(double x) { return x < -eps ? -1 : x > eps ? 1 : 0; }
整型比較 | 等價的浮點數比較 |
---|---|
a == b |
sgn(a - b) == 0 |
a > b |
sgn(a - b) > 0 |
a >= b |
sgn(a - b) >= 0 |
a < b |
sgn(a - b) < 0 |
a <= b |
sgn(a - b) <= 0 |
a != b |
sgn(a - b) != 0 |
用scanf
輸入浮點數時,double
的佔位符是%lf
,可是浮點數double
在printf
系列函數中的標準佔位符是%f
而不是%lf
,使用時最好使用前者,由於雖而後者在大部分的計算機和編譯器中能獲得正確結果,但在有些狀況下會出錯(好比在POJ上)。
當提供給C語言中的標準庫函數double sqrt (double x)
的x
爲負值時,sqrt
會返回nan
,輸出時會顯示成nan
或-1.#IND00
(根據系統的不一樣)。在進行計算幾何編程時,常常有對接近零的數進行開方的狀況,若是輸入的數是一個極小的負數,那麼sqrt
會返回nan
這個錯誤的結果,致使輸出錯誤。解決的方法就是將sqrt
包裝一下,在每次開方前進行判斷。
double mysqrt(double x) { return max(0.0, sqrt(x)); }
大部分的標程的輸出是不會輸出負零的,以下面這段程序:
int main() { printf("%.2f\n", -0.0000000001); return 0; }
會輸出-0.00
。有時這樣的結果是錯誤的,因此在沒有Special Judge的題目要求四捨五入時,不要忘記對負零進行特殊判斷。
但有的標程也不會進行這樣的特殊判斷,因此在WA時不要放棄摸索。
「年代久遠」的緣故,上面的錯誤已經找不到原來的代碼了。 若是各位刷題時出現鬧鬼代碼,歡迎編輯在此,以供後人抓鬼。