亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Visual?Studio實(shí)用調(diào)試技巧大全

 更新時(shí)間:2023年06月19日 09:15:20   作者:憶夢初心  
這篇文章主要給大家介紹了關(guān)于Visual?Studio實(shí)用調(diào)試技巧的相關(guān)資料,如果你還沒有使用過這些技巧,希望這篇博文能幫你發(fā)現(xiàn)它們,它們學(xué)起來很容易,能幫你節(jié)省很多時(shí)間,需要的朋友可以參考下

一.什么是BUG??

Bug一詞的原意是蟲子,而在電腦系統(tǒng)或程序中隱藏著的一些未被發(fā)現(xiàn)的缺陷或問題,人們也叫它"bug"。這是為什么呢?這就要追溯到一個(gè)程序員與飛蛾的故事了。

Bug的創(chuàng)始人格蕾絲·赫柏(Grace Murray Hopper),是一位為美國海軍工作的電腦專家,也是最早將人類語言融入到電腦程序的人之一。而代表電腦程序出錯(cuò)的“bug” 這名字,正是由赫柏所取的。1947年9月9日,赫柏對(duì)Harvard Mark II設(shè)置好17000個(gè)繼電器進(jìn)行編程后,技術(shù)人員正在進(jìn)行整機(jī)運(yùn)行時(shí),它突然停止了工作。于是他們爬上去找原因,發(fā)現(xiàn)這臺(tái)巨大的計(jì)算機(jī)內(nèi)部一組繼電器的觸點(diǎn)之間有一只飛蛾,這顯然是由于飛蛾受光和熱的吸引,飛到了觸點(diǎn)上,然后被高電壓擊死。所以在報(bào)告中,赫柏用膠條貼上飛蛾,并把“bug”來表示“一個(gè)在電腦程序里的錯(cuò)誤”,“Bug”這個(gè)說法一直沿用到今天。

格蕾絲·赫柏的報(bào)告

二.調(diào)試及其重要性??

2.1 什么是調(diào)試

所有發(fā)生的事情都一定有跡可循,如果問心無愧,就不需要掩蓋也就沒有跡象了,如果問心有愧,就必然需要掩蓋,那就一定會(huì)有跡象,跡象越多就越容易順藤而上,這就是 推理的途徑。順著這條途徑順流而下就是犯罪,逆流而上,就是真相。

而我們程序員就好比一個(gè)偵探,一個(gè)用來尋找bug,修改bug的偵探。人們將這個(gè)過程叫做"Debug"(中文稱作"調(diào)試"),意即"捉蟲子"或"殺蟲子"。每一次調(diào)試都是嘗試破案的過程。

調(diào)試(英語:Debugging / Debug),又稱除錯(cuò),是發(fā)現(xiàn)和減少計(jì)算機(jī)程序或電子儀器設(shè)備中程序錯(cuò)誤的一個(gè)過程。

2.2 調(diào)試的基本步驟

  • 發(fā)現(xiàn)程序錯(cuò)誤的存在
  • 以隔離、消除等方式對(duì)錯(cuò)誤進(jìn)行定位
  • 確定錯(cuò)誤產(chǎn)生的原因
  • 提出糾正錯(cuò)誤的解決辦法
  • 對(duì)程序錯(cuò)誤予以改正,重新測試
本文將詳細(xì)介紹在windows系統(tǒng)的 VS環(huán)境下的調(diào)試過程。

2.3 Debug與Release的介紹

在VS中,我們會(huì)發(fā)現(xiàn)我們的程序可以在兩個(gè)環(huán)境下運(yùn)行,這兩個(gè)環(huán)境就是Debug版本和Release版本,它們二者有何區(qū)別呢?

VS中的Debug與Release

Debug 通常稱為 調(diào)試版本,它包含調(diào)試信息,并且不作任何優(yōu)化, 便于程序員調(diào)試程序。
Release 稱為 發(fā)布版本,它往往是 進(jìn)行了各種優(yōu)化,使得程序在代碼大小和運(yùn)行速度上都是最優(yōu)的, 以便用戶很好地使用。

我們可以分別在兩種環(huán)境下編譯代碼生成對(duì)應(yīng)的可執(zhí)行程序如下:

顯然,Release版本的可執(zhí)行文件比Debug版本的小很多,說明編譯器對(duì)其作了優(yōu)化。

因此,我們?nèi)粘Kf的調(diào)試是在Debug版本的環(huán)境下進(jìn)行的,這是因?yàn)镽elease版本在不加以配置的情況下其調(diào)試信息會(huì)被編譯器優(yōu)化,對(duì)于程序員來說,調(diào)試基本都是在Debug環(huán)境下運(yùn)行(本文下面的調(diào)試也都是在Debug環(huán)境下進(jìn)行調(diào)試)。而對(duì)于測試人員來說,由于要站在用戶的角度上來測試程序是否能正常使用,因此測試是在Release版本的環(huán)境下進(jìn)行的。

??但不排除編寫的程序在Debug環(huán)境下沒有問題,在Release版本出現(xiàn)問題的情況。有些問題在Release環(huán)境下才會(huì)浮現(xiàn),這時(shí)我們就需要對(duì)Release版本進(jìn)行配置,進(jìn)行"調(diào)試"排查錯(cuò)誤。我們有以下幾種方法:

1.項(xiàng)目 -> 屬性 -> C/C++ -> 優(yōu)化 -> 禁用優(yōu)化,通過禁用優(yōu)化使其能生成調(diào)試信息進(jìn)行排錯(cuò),如下:

2.在項(xiàng)目 -> 屬性 -> C/C++ -> 優(yōu)化界面處,將選項(xiàng)逐個(gè)改為對(duì)應(yīng)的Debug選項(xiàng),如/O2改為/O1、/Oy改為/Oy-或者將運(yùn)行時(shí)間優(yōu)化改為程序大小優(yōu)化。注意的是,一般一次只改一個(gè)選項(xiàng),通過觀察改哪個(gè)選項(xiàng)時(shí)錯(cuò)誤消失來鎖定該選項(xiàng)相關(guān)的錯(cuò)誤,針對(duì)性地查找。個(gè)人較推薦這種方法。

話又說回來,Release版本下編譯器到底可能會(huì)做什么優(yōu)化呢?請(qǐng)看如下代碼:

#include <stdio.h>
 
int main()
{
    int i = 0;
    int arr[10] = {0};
    for(i=0; i<=12; i++)
   {
        arr[i] = 0;
        printf("hehe\n");
   }
    return 0;
}

我們很容易就發(fā)現(xiàn)對(duì)數(shù)組進(jìn)行了越界訪問,當(dāng)程序運(yùn)行起來時(shí)應(yīng)該會(huì)崩潰。但是在Debug環(huán)境下我們發(fā)現(xiàn)程序并沒有崩潰而是陷入了死循環(huán):

我們運(yùn)行調(diào)試代碼轉(zhuǎn)到反匯編如下:

我們知道,數(shù)據(jù)在棧上的開辟是從高地址向低地址處開辟的,因此在Debug環(huán)境下變量i的地址比數(shù)組arr的地址高。而在數(shù)組內(nèi)部數(shù)據(jù)的存儲(chǔ)是從低地址向高地址的,因此首元素地址arr是在數(shù)組所在空間的低位,如下:

我們很驚訝的發(fā)現(xiàn)(arr+12)就是變量i的地址。當(dāng)循環(huán)過程中i等于12時(shí),此時(shí)將arr[i]改為0就等價(jià)于將i的值修改為0,然后i++后i等于1小于12,繼續(xù)進(jìn)行循環(huán),依次反復(fù)形成了死循環(huán)。如下:

整個(gè)過程簡化圖如下:

而在Release版本的環(huán)境下程序并不會(huì)出現(xiàn)死循環(huán)的問題:

我們可以打印出此時(shí)變量i和數(shù)組在棧上的地址如下:

我們發(fā)現(xiàn)此時(shí)變量i被編譯器優(yōu)化到低地址處,arr[12]存儲(chǔ)的值就不是i了,便不會(huì)出現(xiàn)死循環(huán)的情況。

綜上,以上代碼在Release版本下,編譯器使 變量在內(nèi)存中開辟的順序發(fā)生了變化,影響到了程序執(zhí)行的結(jié)果,這便是優(yōu)化帶來的好處。

三.windows環(huán)境下調(diào)試介紹?

首先第一步,我們需要將環(huán)境切換為Debug版本,才能進(jìn)行調(diào)試

3.1 常用快捷鍵介紹

以下是在調(diào)試過程中最為常用的幾個(gè)快捷鍵:

快捷鍵

功能

Ctrl+F5

開始執(zhí)行而不進(jìn)行調(diào)試。用于想讓程序直接運(yùn)行起來而不調(diào)試時(shí)。

F9

作用:創(chuàng)建斷點(diǎn)和取消斷點(diǎn)

斷點(diǎn):可以使程序在任何你想停下的地方停止執(zhí)行,繼而一步步執(zhí)行下去。我們可以在任何地方設(shè)置斷點(diǎn),一個(gè)程序也可以有多個(gè)斷點(diǎn)。

F10

逐過程,通常用來處理一個(gè)過程,一個(gè)過程可以是一次函數(shù)調(diào)用,或者是一條語句。

F11

逐語句,每次只執(zhí)行一條語句,我們可以通過這個(gè)快捷鍵使我們的執(zhí)行邏輯進(jìn)入函數(shù)內(nèi)部(這是F10所不具備的,F(xiàn)11是我們?cè)谡{(diào)試過程中最常用的)

F5

啟動(dòng)調(diào)試到下一斷點(diǎn)處,需要配合F9進(jìn)行使用,如果程序沒有斷點(diǎn)則無異于Ctrl+F5

快捷鍵用法

我們還可以對(duì)某一斷點(diǎn)設(shè)置停止條件,方法是 右鍵斷點(diǎn)->單擊條件->輸入斷點(diǎn)條件->關(guān)閉

例如:我們需要讓程序停止在第4次循環(huán)處,我們可以輸入i==4

此時(shí)單擊F5運(yùn)行到斷點(diǎn),我們查看自動(dòng)窗口發(fā)現(xiàn)程序在停止時(shí)i的值為4

3.2 在調(diào)試過程中查看程序當(dāng)前信息

開啟調(diào)試后,我們可以在VS上方的調(diào)試->窗口看到許多用來查看數(shù)據(jù)信息的窗口:

3.3.1 監(jiān)視窗口

通過監(jiān)視窗口我們可以查看我們想要查看的 變量甚至是表達(dá)式的值在程序運(yùn)行過程中的變化,十分靈活,這是我們調(diào)試中用得最多的窗口之一。如下:

3.3.2 自動(dòng)窗口

打開自動(dòng)窗口后,編譯器會(huì)將一些可能需要觀察的變量顯示在窗口中,較為方便。其缺陷是可能無法顯示我們真正需要觀察的變量,并且 無法靈活顯示表達(dá)式等的值。如下:

3.3.3 局部變量窗口

打開局部變量變量窗口,會(huì)將程序中的所有 局部變量全部顯示出來。如下:

3.3.4 調(diào)用堆棧窗口

通過調(diào)用堆棧,可以清晰的反應(yīng) 函數(shù)的調(diào)用關(guān)系以及當(dāng)前調(diào)用所處的位置。如下:

通過調(diào)用堆棧窗口,我們可以發(fā)現(xiàn),show函數(shù)棧幀在main函數(shù)棧幀之上,即 show函數(shù)是由main函數(shù)調(diào)用的。并且可以看出此時(shí)show函數(shù)運(yùn)行到第20行。

3.3.5 內(nèi)存窗口

通過內(nèi)存窗口我們可以看到內(nèi)存中的信息,可以 觀察變量在內(nèi)存中的存儲(chǔ)情況。如下:

3.3.6 反匯編

我們可以查看當(dāng)前程序轉(zhuǎn)化后的匯編代碼,進(jìn)而從更底層的角度觀察程序的執(zhí)行過程。如下:

3.3.7 寄存器

通過寄存器窗口,我們可以觀察在當(dāng)前環(huán)境下CPU內(nèi)的寄存器的使用信息,如ebp棧底寄存器、esp棧頂寄存器等等。

3.3 調(diào)試實(shí)例

我們上面通過調(diào)試分析了數(shù)組越界陷入死循環(huán)的問題。下面,我們?cè)偻ㄟ^一道實(shí)例來掌握調(diào)試的技巧:

實(shí)現(xiàn)代碼:求 1!+2!+3! ...+ n! ;不考慮溢出。我們可能會(huì)寫出以下代碼:
#include<stdio.h>
int main()
{
    int i = 0;
    int sum = 0;//保存最終結(jié)果
    int n = 0;
    int ret = 1;//保存n的階乘
    scanf("%d", &n);
    for(i=1; i<=n; i++)
    {
        int j = 0;
        for(j=1; j<=i; j++)
        {
            ret *= j;
        }
        sum += ret;
    }
    printf("%d\n", sum);
    return 0;
}
當(dāng)你輸入3時(shí),理論上應(yīng)該輸出9,但實(shí)際上程序卻輸出了15:

是什么問題導(dǎo)致出錯(cuò)了呢?這就需要我們動(dòng)手進(jìn)行調(diào)試。在調(diào)試之前我們可以先 預(yù)測問題的所在,比如 算階乘時(shí)出錯(cuò)、 求和時(shí)出錯(cuò)等等。做到心里有數(shù),而不是盲目的進(jìn)行調(diào)試。

我們可以在ret*=j處設(shè)置一個(gè)斷點(diǎn),打開監(jiān)視窗口監(jiān)視r(shí)et和sum觀察每個(gè)數(shù)階乘的值和累加后的值,如下:

我們單擊F10逐過程執(zhí)行,當(dāng)外層循環(huán)i的值為3時(shí),即計(jì)算3的階乘時(shí),我們發(fā)現(xiàn)ret的初始值并非為1,而是2的階乘。此時(shí)再計(jì)算3的階乘,就是2*1*2*3=12 != 6,結(jié)果出錯(cuò):

最后sum+ret的值就為15,與我們的輸出相符:

可見,每次在求階乘時(shí),我們都應(yīng)該把ret重置為1,正確的代碼如下:

int main()
{
    int i = 0;
    int sum = 0;//保存最終結(jié)果
    int n = 0;
    int ret = 1;//保存n的階乘
    scanf("%d", &n);
    for (i = 1; i <= n; i++)
    {
        int j = 0;
        ret = 1; //將ret置1
        for (j = 1; j <= i; j++)
        {
            ret *= j;
        }
        sum += ret;
    }
    printf("%d\n", sum);
    return 0;
}

3.4 實(shí)踐出真知

任何事情都不可能一蹴而就,一定要多加練習(xí),才能熟練掌握調(diào)試技巧。

一個(gè)初學(xué)者可能80%的時(shí)間在寫代碼,20%的時(shí)間在進(jìn)行調(diào)試;而一個(gè)程序員,可能80%的時(shí)間在進(jìn)行調(diào)試,剩余20%的時(shí)間才是在寫代碼。

隨之學(xué)習(xí)的深入,后續(xù)可能會(huì)出現(xiàn)很多更加復(fù)雜的調(diào)試場景,如多線程等。只有打好基礎(chǔ),在未來才能融會(huì)貫通,利于不敗之地。

多多使用快捷鍵可以很大程度上提高效率。

四.如何寫出便于調(diào)試的優(yōu)秀代碼

4.1 什么是優(yōu)秀的代碼

1. 代碼運(yùn)行正常
2. bug很少
3. 效率高
4. 可讀性高
5. 可維護(hù)性高
6. 注釋清晰
7. 文檔齊全

4.2 常用coding(編碼)技巧

1.多使用assert斷言,可以告知你出錯(cuò)的位置
2.盡量使用const,避免意外修改
3.養(yǎng)成良好的編碼風(fēng)格
4.添加必要的注釋
5.避免編碼的陷阱

4.3 實(shí)例

試模擬實(shí)現(xiàn)一個(gè)strcpy函數(shù),盡量用到上述的編碼技巧。如下:
char* strcpy(char* dst, const char* src) //const修飾防止對(duì)源字符串進(jìn)行修改
{
    assert(dst && src); //避免傳入空指針
    char cur = dst; //保存起始位置
    //將src的字符一個(gè)個(gè)拷貝到det中,包括'\0'
    while ((*dst++ = *src++)!='\0')
    {
        ;
    }
    return cur; //返回目標(biāo)字符串,以便鏈?zhǔn)皆L問
}

五.編程中常見的錯(cuò)誤

5.1 編譯型錯(cuò)誤

在 編譯期間出現(xiàn)的錯(cuò)誤。直接看錯(cuò)誤提示信息(雙擊鼠標(biāo)),解決問題。或者憑借經(jīng)驗(yàn)就可以搞定。相對(duì)來說簡單。

5.2 鏈接型錯(cuò)誤

在 鏈接期間出現(xiàn)的錯(cuò)誤??村e(cuò)誤提示信息,主要在代碼中找到錯(cuò)誤信息中的標(biāo)識(shí)符,然后定位問題所在。一般是 標(biāo)識(shí)符名不存在或者 拼寫錯(cuò)誤。

5.3 運(yùn)行時(shí)出錯(cuò)

在 運(yùn)行期間出現(xiàn)的錯(cuò)誤。借助 調(diào)試,逐步定位問題。最難搞的一種錯(cuò)誤
不要害怕遇到錯(cuò)誤,每出現(xiàn)一次的錯(cuò)誤就是一次突破自我的機(jī)會(huì)。
學(xué)會(huì)積累排錯(cuò)經(jīng)驗(yàn),勇于嘗試。不經(jīng)風(fēng)雨 ?? ,怎能見彩虹 ??

以上,就是本期的全部內(nèi)容啦??

總結(jié)

到此這篇關(guān)于Visual Studio實(shí)用調(diào)試技巧大全的文章就介紹到這了,更多相關(guān)VS調(diào)試技巧內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • VSCode自定義配色方案的實(shí)現(xiàn)

    VSCode自定義配色方案的實(shí)現(xiàn)

    這篇文章主要介紹了VSCode自定義配色方案的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • 在PB中如何讓用戶只能修改新增的數(shù)據(jù)

    在PB中如何讓用戶只能修改新增的數(shù)據(jù)

    一些數(shù)據(jù)庫系統(tǒng)或者某些數(shù)據(jù)表只允許用戶添加數(shù)據(jù),而不能修改或者刪除以往的記錄,此時(shí)我們就必須在程序進(jìn)行控制。有些程序員通過不顯示以往的數(shù)據(jù)來保證,下面我們介紹一種既可以看到原始記錄,有不容許用戶修改這些記錄的方法
    2008-11-11
  • git merge最簡潔用法詳解

    git merge最簡潔用法詳解

    git-merge 命令是用于從指定的 commit(s) 合并到當(dāng)前分支的操作,本文重點(diǎn)給大家介紹git merge最簡潔用法,感興趣的朋友跟隨小編一起看看吧
    2020-12-12
  • 編程之顯示/隱式聲明

    編程之顯示/隱式聲明

    顯示聲明 是程序中的一條說明語句,它列出一批變量名并指明這些變量的類型。隱式聲明 指通過某種默認(rèn)協(xié)定的方法將變量名與類型綁定。
    2011-01-01
  • 關(guān)于401狀態(tài)碼的含義和處理方式

    關(guān)于401狀態(tài)碼的含義和處理方式

    這篇文章主要介紹了關(guān)于401狀態(tài)碼的含義和處理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • 算法系列15天速成——第十五天 圖【下】(大結(jié)局)

    算法系列15天速成——第十五天 圖【下】(大結(jié)局)

    今天是大結(jié)局,說下“圖”的最后一點(diǎn)東西,“最小生成樹“和”最短路徑“
    2013-11-11
  • Sublime?Text?4怎么安裝使用

    Sublime?Text?4怎么安裝使用

    這篇文章主要介紹了Sublime?Text?4怎么安裝使用,下載對(duì)應(yīng)的安裝包,將該exe文件復(fù)制到對(duì)應(yīng)的sublime?text的安裝目錄下(與sublime_text.exe同級(jí)),右鍵管理員運(yùn)行即可,需要的朋友跟隨小編一起看看吧
    2022-01-01
  • yum安裝telnet的步驟

    yum安裝telnet的步驟

    Telnet協(xié)議是TCP/IP協(xié)議族中的一員,是Internet遠(yuǎn)程登錄服務(wù)的標(biāo)準(zhǔn)協(xié)議和主要方式,Telnet是常用的遠(yuǎn)程控制Web服務(wù)器的方法,本文給大家分享yum安裝telnet的步驟,感興趣的朋友一起看看吧
    2020-05-05
  • 五個(gè)最佳編程文本編輯器分享

    五個(gè)最佳編程文本編輯器分享

    五個(gè)最佳編程文本編輯器分享,經(jīng)常編寫代碼的朋友可以參考下
    2012-04-04
  • 網(wǎng)站分站的實(shí)現(xiàn)方法

    網(wǎng)站分站的實(shí)現(xiàn)方法

    現(xiàn)在一般的行業(yè)門戶網(wǎng)站為了業(yè)務(wù)的發(fā)展和網(wǎng)絡(luò)推廣,一般都會(huì)開通幾個(gè)地區(qū)和子行業(yè)的分站。下面是一些解決思路,需要的朋友可以參考下。
    2010-06-06

最新評(píng)論