如何用VS進行程序調試


VS是一個強大的IDE,如果你現在只會簡單地用它查看一下執行效果,那就太大材小用了。

1. CRT函數報錯

首先來說說最常見的一個編譯錯誤。微信里常常收到這個錯誤的截圖提問。

CRT(C Runtime Library = C運行時間庫)是windows平台下的一個概念。CRT函數准的C語言函數。例如:printf、scanf、strlen、fopen等函數都屬於CRT函數。

安全CRT函數是微軟對C/C++的擴展,對大部分的CRT函數都派生了一個新的函數形式。比如把fopen函數重新定義如下:

errno_t fopen_s(FILE** pFile, const char *filename, const char *mode);

微軟認為,使用這種函數能夠幫助開發者更好地規避內存泄露、空指針訪問等常見問題。為了盡量讓大家養成使用安全CRT的習慣,在編譯沒有使用安全CRT函數的代碼時,VS會報出如下錯誤:

Error 1 error C4996: 'freopen': This function or variable may be unsafe.
Consider using freopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS.
See online help for details. e:\c\vstestc\vstestc\fileoper.c 8 1 VSTestC

如果你想讓自己的代碼寫的更通用,不想使用微軟的所謂安全CRT函數,可以使用下面的方法:

1.1 代碼中定義宏

如果你仔細越短報錯信息,就會發現其實VS已經告訴你怎么解決了。只要定義一下_CRT_SECURE_NO_WARNINGS就能解決。把下面的句子寫在代碼中:

#define _CRT_SECURE_NO_WARNINGS

現在編譯是不是就成功了。

1.2 工程中配置

如果非安全CRT函數用在很多不同的文件中,由於作用域的關系,你可能需要在多處寫下宏定義語句。這樣不太方便,這時候你可以選擇在工程配置中一勞永逸的解決這個問題。步驟如下:

  • 打開工程屬性界面

在工程名上右鍵,選擇“Properties”,進入下面的界面。

  • 宏定義添加窗口

如圖,選擇“Configuration Properties” -> “C/C++” -> “Preprocessor” -> “Preprocessor Definitions”。點擊右邊的下拉箭頭,之后點擊“Edit”。

  • 添加宏定義

_CRT_SECURE_NO_WARNINGS添加到List中。

之后,點擊OK。

現在編譯試試,報錯沒有了。

1.3 靜態引用運行時庫

打開打開工程屬性界面,選擇“C/C++” -> “Code Generation” -> “Runtime Library”。

如圖,默認情況下是動態引用。我們需要改成靜態引用。

下拉窗中的四個選項意義如下。

對與debug版本的程序:

  • /MTd 靜態引用運行時庫的debug版本
  • /MDd 動態引用運行時庫的debug版本

對與release版本的程序:

  • /MT 靜態引用運行時庫的release版本
  • /MD 動態引用運行時庫的release版本

1.4 忽略警告

報錯信息中,有這樣一部分error C4996:,這是這個問題的錯誤碼。我們可以顯示地要求VS不要提示這種問題的信息。只要在代碼開始的部分加入下面這句話即可:

#pragma warning(disable:4996)

問題是不是解決了。

2. 查看運行結果

#include int main() { printf("Hello world!"); return 0; }

上面這段代碼,如果直接按F5運行,你會看到一個一閃而過的控制台窗口。這個窗口出現的時間很短,以至於很難看清楚結果。解決這個問題又很多方法,常見的大概有下面四種:

2.1 Ctrl + F5

這個是最常見的方法,按下Ctrl + F5組合鍵,會看到下面這個結果:

美中不足的是系統會自動添加一行字:“請按任意鍵繼續...”。當你按任意鍵之后,窗口消失。

2.2 斷點

如圖所示,在最后一行代碼處打斷點。之后,按F5開始調試執行程序,會看到下面這個結果:

程序被停在斷點處,而命令行窗口也被停下了。看完結果后,只需要再按一下F5繼續執行程序,它就會正常結束。

2.3 getch()

通過getch函數,可以實現和2.1相同的效果,不過沒有哪行字。代碼如下:

int main() { printf("Hello world!"); getch(); return 0; }

執行這段代碼,命令行會停在新加這行代碼執行后,直到按下任意鍵程序才繼續執行到結束。

2.4 system("pause")

system函數是不是很熟悉,上一篇文章中我們已經認識過了。加上這句話其實是調用了系統提供的pause這個命令。效果和2.1完全相同。

3. 單步調試

依然是前面那段代碼,我們按F10鍵來進行單步調試。

左邊黃色的箭頭表示當前程序的執行位置。按一下F10鍵,箭頭指向的這行代碼就被執行,同時箭頭指向下一行。這樣完全按照程序運行的過程執行。

如果程序是這樣,在調用Function函數時,如果按F10,程序會一次執行完整個Function函數。但如果你按F11,箭頭會進入Function函數內部,就像這樣:

在程序運行中,把鼠標停留在一個變量上,此時會看到這個變量當前的值。如下圖:

當然,還可以把這個變量拖入watch窗口,這樣就能實時查看這個變量的變化:

單步調試還有很多神奇之處需要你慢慢發現。這部分內容不好講,不過你只要稍微操作一下就能學會。

4. 條件斷點

int main() { int i; for (i = 0; i < 100; i++) { printf("i = %d\n", i); } return 0; }

這段代碼很簡單,打印0~99這100個數,假如,我是說假如你的程序運行到第95次循環時出現了問題,如果你想單步調試看看i的變化情況,你不可能一直按F10直到第95次循環。那樣手肯定吃不消。這時候,就用到了條件斷點的方法。修改代碼如下:

如圖,添加一組 if 語句,把斷點打在 if 中的代碼里。現在按F5調試執行,程序會在第95次循環中我們打斷點的地方停下,之后你再按F10單步調試就好了。是不是簡單多了。

5. 調試的樂趣

調試代碼能夠讓編程變得不那么枯燥。當你一步一步跟着程序的執行方式去思考問題,你會更加深刻地體會計算機的某些邏輯。

另外,在你寫程序時,腦子里想的是如何設計代碼,但在你調試的過程你會在另外一個角度去審慎這段代碼,這時你很容易發現其中的不足之處。很多情況下,一個程序有問題,看代碼怎么也發現不了究竟錯在哪里,不過一調試就能馬上找到。

學會了代碼調試,你的編程學習就算是真正入門了。它不僅僅是你軟件開發中的工具,也是編程學習過程中不斷提高和不斷自我完善的神奇。

 


學習過程中遇到什么問題或者想獲取學習資源的話,歡迎加入學習交流群
639368839,我們一起學C/C++!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM