下面的錯誤非常經典, 很容易發生, 程式寫好以後很難找到這種錯誤, 說起來也算是一種很有價值的錯誤, 遇見一次如果你能夠徹底了解為什麼會發生這種錯誤, 修改你撰寫程式時思考的邏輯, 你的收穫就很大了。
乘法的錯誤一 |
有些同學寫完乘法以後,
會用類似下面的測試確認程式的功能:
CComplex x1, x2, x3; x1.setValue(2, 0); x2.setValue(3, 0); x3.setValue(6, 0); x1.multiply(x2); assert(x1.equal(x3, 1e-10));為什麼只測試實數呢? 這樣子不是沒有測試到完整的功能嗎? 有可能是因為如果有虛數的話, 乘起來的結果還需要動腦筋算一算才能得到結果, 有一點點偷懶吧!! 下面這個常常發生的錯誤就是只用實數是測不出來的, 你可以試試下面這個測試 CComplex x1, x2, x3; x1.setValue(1, 2); x2.setValue(3, 4); x3.setValue(-5, 10); x1.multiply(x2); assert(x1.equal(x3, 1e-10));如果你的 multiply 函式沒辦法通過這個測試... 也許你也有下面這樣子的錯誤 void CComplex::multiply(CComplex &rhs) { m_real = m_real*rhs.m_real - m_imaginary*rhs.m_imaginary; m_imaginary = m_real*rhs.m_imaginary + m_imaginary*rhs.m_real; }上面這段程式碼為什麼有錯呢? 因為你在算乘積的 m_imaginary 的時候, m_real 已經是乘積的 m_real 了, 不是原來被乘數的 m_real。 |
---|---|
乘法的錯誤二 |
下面這個測試也是想當然爾的功能,
不過很多同學會忽略而沒有測試:
CComplex x1, x2; x1.setValue(1, 2); x2.setValue(-3, 4); x1.multiply(x1); assert(x1.equal(x2, 1e-10));你的程式通過測試了嗎? 如果沒有的話, 也許是犯了下面這樣的錯誤: void CComplex::multiply(CComplex &rhs) { double temp; temp = m_real; m_real = m_real*rhs.m_real - m_imaginary*rhs.m_imaginary; m_imaginary = temp*rhs.m_imaginary + m_imaginary*rhs.m_real; }上面這段程式碼為什麼有錯呢? 不是已經用 temp 把被乘數的 m_real 記下來了嗎?! 錯誤的原因是 "你假設 rhs 在計算過程中是不會被修改的", 這是很容易犯的錯, 真的沒有被改到嗎? 被乘數和乘數一定是不同的數嗎? 不會相同嗎? 再一次的提醒你, 並不是數學公式有錯, 而是你撰寫這段程式時作了一個錯誤的假設 - "被乘數和乘數是不同的數"。 正確的寫法應該像這樣: void CComplex::multiply(CComplex &rhs) { double lhsReal, rhsReal; lhsReal = m_real; rhsReal = rhs.m_real; m_real = m_real*rhs.m_real - m_imaginary*rhs.m_imaginary; m_imaginary = lhsReal*rhs.m_imaginary + m_imaginary*rhsReal; }或是 void CComplex::multiply(CComplex &rhs) { CComplex newNumber; newNumber.m_real = m_real*rhs.m_real - m_imaginary*rhs.m_imaginary; newNumber.m_imaginary = m_real*rhs.m_imaginary + m_imaginary*rhs.m_real; *this = newNumber; // m_real = newNumber.m_real; // m_imaginary = newNumber.m_imaginary; } |
回
C++ 物件導向程式設計課程
首頁
製作日期: 03/28/2007
by 丁培毅 (Pei-yih Ting)
E-mail: pyting@cs.ntou.edu.tw
TEL: 02 24622192x6615
海洋大學
電機資訊學院
資訊工程系
Lagoon