1. 程式人生 > >程式除錯中的常見問題及解決方法【2017.9.27更新】

程式除錯中的常見問題及解決方法【2017.9.27更新】

1、CE(Compile Error)編譯錯誤

其實很多時候通過返回的錯誤資訊就能找出錯誤。

①缺失符號,如下圖

缺失分號
第一句Error表示在“printf”前少了一個分號,
第二句Error表示在“return”前少了一個分號。
通常在錯誤行的上一行找缺失的分號。比如,

    int main()
    {
        int sas   //here;
        printf("%d",a[7]);
        if(1)
        a[0]=1   //here;
        return 0;
    }

根據程式碼和上面圖片的資訊,很容易判斷錯誤在哪。

②缺失引數

比如這樣:

void f(int a)
{
    ......
}
int main()
{
    f();
    return 0;
}

就會有這樣的錯誤資訊返回:

[Error] too few arguments to function ‘void f(int)’

說明我們在使用函式時給予的引數過少。

③語句不明確

例如我們在使用string的時候,想要把字串a賦為“abcde”。

於是我們寫成了這樣:

string a=abcde;

錯誤資訊:

[Error] ‘abcde’ was not declared in this scope

我們應該清楚這是什麼原因,計算機認為“abcde”是一個變數,但我們認為它是一個字串。

怎麼處理呢?

加個雙引號。

string a="abcde";

④函式型別不正確

int 類的函式就要返回一個int值,void函式就要直接return,搞錯這個很容易出事的。

比如我們搞錯了:

void f()
{
    return 1;
}

錯誤資訊:

這裡寫圖片描述

看起來好複雜,其實就是void函式return了int值。把return 1; 改成return;就好了

*如果使用了STL,並且是STL相關語句CE,那麼錯誤資訊可能很複雜。

但是不要怕,錯誤本身可能並不是多麼複雜。

所以下面說一個sort常見的問題。

#include<cstdio>
#include<algorithm>
using namespace std;
struct A
{
    int v,c;
}a[15];
int main()
{
    for(int i=1;i<=10;i++)
        scanf("%d",&a[i]);
    sort(a+1,a+11);
}

然後就CE 了··· 而且錯誤資訊辣麼多QAQ
還會跳出來一串程式碼:

  template<typename _RandomAccessIterator>
    void
    __insertion_sort(_RandomAccessIterator __first,
             _RandomAccessIterator __last)
    {
      if (__first == __last)
    return;

      for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
    {
      if (*__i < *__first)
        {
          typename iterator_traits<_RandomAccessIterator>::value_type
        __val = _GLIBCXX_MOVE(*__i);
          _GLIBCXX_MOVE_BACKWARD3(__first, __i, __i + 1);
          *__first = _GLIBCXX_MOVE(__val);
        }
      else
        std::__unguarded_linear_insert(__i);
    }
   }

看不懂啊QAQ
不過沒關係,我們知道錯誤行是這個:

if (*__i < *__first){···}

啥意思呢?想想sort是用來幹什麼的?排序,對吧。而我們的a是一個結構體,裡面包含著c,v兩個數。
於是就得出結論:程式不知道按什麼來排序了。
怎麼辦呢?手寫cmp函式。
如果想按c排序,就這樣:

bool cmp(A a,A b)
{
    return a.c<b.c;
}

然後把sort改一下:

sort(a+1,a+11,cmp);

就這樣,編譯通過!

2、RE(Running Error)執行時錯誤

執行時崩潰

圖有點大=V=

具體來說有以下解決方法:
①檢查在scanf中是否加入了%、&等必要符號。
②檢查陣列是否越界(陣列下標為負數、陣列下標過大)。
③如果使用了STL,請認真檢查與STL相關的語句,不管是函式還是資料結構。
④如果使用了指標,檢查指標是否初始化為NULL。
⑤檢查是否遞迴了太多次,導致爆棧。

3、WA(Wrong Answer)

先想想自己演算法的正確性吧。

演算法沒錯?看下面:

一、程式輸出了意料之外的結果,如0、極大值。

①是不是陣列沒有賦初值?
②是不是訪問了非法記憶體(有時訪問非法記憶體不會RE)?
③迴圈次數是否遠遠超過或低於預期?
④是不是爆int了?

二、程式輸出的結果與推算的不一致,但差別不大。

①看看有沒有把初值賦錯。
②看看有沒有把“==”寫成了“=”。
③看看有沒有弄混“>”“<”“>=”“<=”
④變數型別對不對?輸出型別對不對(如scanf(“%c”,(int)a);)?

三、熟練運用除錯功能。

不一定要開啟除錯面板除錯,輸出中間變數也是一個很好的方法。
通過對比一個(或多個)關鍵變數在程式中的變化與預期變化的差距,往往能發現問題。

4、AC(Accepted)

那你很棒棒喲!⊙v⊙

嘛,以後還會更新的。