摘要:臭蟲中文常稱為缺陷。與相對應(yīng),人們將發(fā)現(xiàn)并加以糾正的過程叫做中文稱作調(diào)試,意即捉蟲子或殺蟲子。于是,霍珀詼諧的把程序故障統(tǒng)稱為臭蟲,把排除程序故障叫,而這奇怪的稱呼,后來成為計(jì)算機(jī)領(lǐng)域的專業(yè)行話。
各位小伙伴們大家好,我是澤奀( ̄o ̄) . 相信大家在編寫C程序中會遇到很多代碼的Bug.所以本篇博客就帶大家如何調(diào)試C的技巧,這樣在遇到有錯誤的代碼,也不必驚慌,只需調(diào)試下,Bug就再也不會存在了哈哈哈~隔。?
?目錄
bug:Bug的原意:可以稱之為“臭蟲",現(xiàn)在指代的是漏洞,就是在安全系統(tǒng)上出現(xiàn)缺陷,攻擊者可以對未授權(quán)的情況下進(jìn)行攻擊,Bug(計(jì)算機(jī)漏洞) 可以形容在各個領(lǐng)域范圍之內(nèi)所出現(xiàn)的漏洞。
由來:第一代的計(jì)算機(jī)是由許多龐大且昂貴的真空管組成,并利用大量的電力來使真空管發(fā)光??赡苷怯捎谟?jì)算機(jī)運(yùn)行產(chǎn)生的光和熱,引得一只小蟲子(Bug)鉆進(jìn)了一支真空管內(nèi),導(dǎo)致整個計(jì)算機(jī)無法正常工作。研究人員費(fèi)了半天時間,總算發(fā)現(xiàn)原因所在,把這只小蟲子從真空管中取出后,計(jì)算機(jī)又恢復(fù)正常。后來,Bug這個名詞就沿用下來,用來表示電腦系統(tǒng)或程序中隱藏的錯誤、缺陷、漏洞等問題。
1945年,計(jì)算機(jī)還是由機(jī)械式繼電器和真空管驅(qū)動的,機(jī)器有房間那么大。體現(xiàn)當(dāng)時技術(shù)水平的MarkⅡ,是由哈佛大學(xué)制造的一個龐然大物。當(dāng)技術(shù)人員正在進(jìn)行不整機(jī)運(yùn)行時,它突然停止了工作。他們爬上去找原因,發(fā)現(xiàn)這臺巨大的計(jì)算機(jī)內(nèi)部一組繼電器的觸點(diǎn)之間有一只飛蛾,這顯然是由于飛蛾受光和熱的吸引,飛到了觸點(diǎn)上,然后被高電壓擊死。與Bug相對應(yīng),人們將發(fā)現(xiàn)Bug并加以糾正的過程叫做“Debug”(中文稱作“調(diào)試”),意即“捉蟲子”或“殺蟲子”。
調(diào)試其實(shí)就是找出bug,計(jì)算機(jī)有bug一定是你程序的問題。所有發(fā)生的程序的問題都是有跡可循的,我們只需要順藤摸瓜最后一步步解決。
一名優(yōu)秀的程序員,必然是一名優(yōu)秀的偵探。每一次的調(diào)試其實(shí)就是破案的過程。
調(diào)試:英文DeBug,又稱作是除錯,是發(fā)現(xiàn)和減少計(jì)算機(jī)程序設(shè)備中和電子儀器錯誤的過程。
代價最小的是程序員,代價最大的是用戶。
通常為調(diào)試版本,它包含的調(diào)試信息,并且不會做進(jìn)行任何的優(yōu)化,便于程序員的調(diào)試信息。
概念:
1937年,美國青年霍華德·艾肯找到IBM公司為其投資200萬美元研制計(jì)算機(jī),第一臺成品艾肯把它取名為:馬克1號(mark1),又叫“自動序列受控計(jì)算機(jī)”,從這時起IBM公司由生產(chǎn)制表機(jī),肉鋪磅秤,咖啡研磨機(jī)等亂七八糟玩意兒行業(yè),正式跨進(jìn)“計(jì)算機(jī)”領(lǐng)地。為馬克1號編制程序的是哈佛的一位女?dāng)?shù)學(xué)家格蕾絲·霍珀,有一天,她在調(diào)試程序時出現(xiàn)故障,拆開繼電器后,發(fā)現(xiàn)有只飛蛾被夾扁在觸點(diǎn)中間,從而“卡”住了機(jī)器的運(yùn)行。于是,霍珀詼諧的把程序故障統(tǒng)稱為“臭蟲.............(BUG)”,把排除程序故障叫DEBUG,而這奇怪的“稱呼”,后來成為計(jì)算機(jī)領(lǐng)域的專業(yè)行話。從而debug意為排除程序故障的意思。
稱之為發(fā)布版本,它往往是根據(jù)各種進(jìn)行了優(yōu)化,使得程序的代碼都是最佳優(yōu)的,以便讓用戶更好的去使用。
Debug和Release編譯方式的本質(zhì)區(qū)別
Debug 通常稱為調(diào)試版本,它包含調(diào)試信息,并且不作任何優(yōu)化,便于程序員調(diào)試程序。
Release 稱為發(fā)布版本,它往往是進(jìn)行了各種優(yōu)化,使得程序在代碼大小和運(yùn)行速度上都是最優(yōu)的,以便用戶很好地使用。還有大小的區(qū)別,因?yàn)镈ebug的版本是可以進(jìn)行調(diào)試的(包含了相應(yīng)的調(diào)試信息),而Release版本是不能進(jìn)行調(diào)試的。
Debug 和 Release 的真正秘密,在于一組編譯選項(xiàng)。
下面列出了分別針對二者的選項(xiàng)
(當(dāng)然除此之外還有其他一些,如/Fd /Fo,但區(qū)別并不重要,通常他們也不會引起 Release 版錯誤,在此不討論)
/MDd /MLd 或 /MTd 使用 Debug runtime library(調(diào)試版本的運(yùn)行時刻函數(shù)庫)
/Od 關(guān)閉優(yōu)化開關(guān)
/D "_DEBUG " 相當(dāng)于 #define _DEBUG,打開編譯調(diào)試代碼開關(guān)(主要針對 assert函數(shù))
/ZI 創(chuàng)建 Edit and continue(編輯繼續(xù))數(shù)據(jù)庫,這樣在調(diào)試過 程中如果修改了源代碼不需重新編譯 /GZ 可以幫助捕獲內(nèi)存錯誤
/Gm 打開最小化重鏈接開關(guān),減少鏈接時間
/MD /ML 或 /MT 使用發(fā)布版本的運(yùn)行時刻函數(shù)庫
/O1 或 /O2 優(yōu)化開關(guān),使程序最小或最快
/D "NDEBUG " 關(guān)閉條件編譯調(diào)試代碼開關(guān)(即不編譯assert函數(shù))
/GF 合并重復(fù)的字符串,并將字符串常量放到只讀內(nèi)存,防止 被修改
實(shí)際上,Debug 和 Release 并沒有本質(zhì)的界限,他們只是一組編譯選項(xiàng)的集合,編譯器只是按照預(yù)定的選項(xiàng)行動。事實(shí)上,我們甚至可以修改這些選項(xiàng),從而得到優(yōu)化過的調(diào)試版本或是帶跟蹤語句的發(fā)布版本。
- 采用Debug的話,如果用Debug代碼來編譯可執(zhí)行程序的話,我們也會產(chǎn)生一個Debug的版本的一個可執(zhí)行程序
- 采用Release的話,就是發(fā)布版本,可執(zhí)行的程序?!ê喕?/span>
#include#includeint main(void){ int i = 0; int arr[10] = {1,2,3,4,5,6,7,8,9,10}; for(i=0;i<=12;i++) { printf("hello C/n"); arr[i] = 0; } system("pause");}
大家可以分別試一下就會發(fā)現(xiàn)不同之處了,分別用Debug和Release運(yùn)行以下程序。這里是當(dāng)你for循環(huán)的結(jié)果為假的時候,它的i又會重置為0,然后一直這個樣子重復(fù)循環(huán)打印for語句的循環(huán)內(nèi)容。因?yàn)閍rr這里跟i它們兩個人是同一塊空間,那么當(dāng)你改變arr[i]的時候int i也會改變。因?yàn)樗鼈兊牡刂肥且粯拥?,所以才會改變?/span>
由于這個程序涉及范圍到棧區(qū)一些相關(guān)的知識點(diǎn)的內(nèi)容,在這里我跟大家簡單的說下。
棧區(qū):棧區(qū)的默認(rèn)使用是先使用高地址處的空間,然后在使用低地址處的空間。數(shù)組的下標(biāo)隨著增長,地址是由低到高變化的。當(dāng)然如果你在不同的編譯器上運(yùn)行它的死循環(huán)的位置可能不同。你們也可以在不同的編譯器上運(yùn)行一下對比一下
運(yùn)行:Ctrl + F11
使用快捷鍵Ctrl + F11可以快速運(yùn)行當(dāng)前選中的資源文件。
調(diào)試:F11:是逐步 它是會進(jìn)入函數(shù)的 把程序細(xì)化到步
shift + F11,跳出函數(shù)
F10 是逐行 在某條語句調(diào)用一個函數(shù)的時候 它不會進(jìn)入(除非那里設(shè)有斷點(diǎn))
F9:切換斷點(diǎn)
使用快捷鍵F11可以快速調(diào)試當(dāng)前選中的資源文件。
斷點(diǎn)調(diào)試操作:F5、F6、F7、F8
F5和F9的快捷鍵可以進(jìn)行配合使用。
在斷點(diǎn)調(diào)試時,快捷鍵F6是執(zhí)行下一步(單步跳過);F5是執(zhí)行當(dāng)前調(diào)用內(nèi)部細(xì)節(jié)步驟的下一步(單步跳入);F7是跳過方法內(nèi)部的執(zhí)行步驟,直接返回到方法外的下一步(單步返回);F8是跳出斷點(diǎn)調(diào)試(跳過調(diào)試,繼續(xù)執(zhí)行代碼,在下一個斷點(diǎn)處暫停再次進(jìn)入斷點(diǎn)調(diào)試)。
ctrl + F5:開始執(zhí)行不調(diào)試,如果你想讓程序而不調(diào)試就可以進(jìn)行使用。
自動窗口:當(dāng)我們程序在執(zhí)行中的時候,打開自動窗口,自動的把某些程序的上下文變量自動給你觀察,這就是自動窗口的功能。
局部變量:和自動窗口差不多其實(shí),但是它有一個缺點(diǎn)是它不能想監(jiān)視誰就監(jiān)視誰。
監(jiān)視:監(jiān)視這個作用就比較好了,當(dāng)你想監(jiān)視的話就輸入那個變量的值,它就會呈現(xiàn)在你的監(jiān)視當(dāng)中,這樣你就可以隨時隨地的去進(jìn)行觀察那個變量了。(監(jiān)視窗口可以說是博主用的最多的了)
內(nèi)存:如果我們想進(jìn)行觀察當(dāng)前程序執(zhí)行的內(nèi)存的話,這個時候就是你輸入觀察的內(nèi)存信息了。
(內(nèi)存窗口也是用的可以說是非常多的了)
調(diào)用堆棧:在這里簡單的和各位小伙伴們說下,像棧一樣的邏輯給大家給展示出來它的一個邏輯,頂上往前放數(shù)據(jù)再往頂上出數(shù)據(jù),可以很好反饋程序當(dāng)中的代碼的調(diào)棧的調(diào)用邏輯。
初學(xué)者掌握調(diào)試的內(nèi)容可以達(dá)到事半功倍的效果,多多使用調(diào)試可以提高程序執(zhí)行代碼的效率。
- 代碼整潔且規(guī)范
- 注釋清晰,且通俗易懂(代指寫代碼的人)
- 可讀性,有效性,可維護(hù)性
- bug盡量能夠達(dá)到自己能夠預(yù)期的范圍之內(nèi),就是bug少,或者幾乎沒有bug
- 文檔齊全,不亂去堆放?
- 養(yǎng)成良好的編碼風(fēng)格
- 注釋必要的還是要去添加,提高代碼的可讀性
- 避免編碼的陷阱
- 盡量使用const
- 使用assert,頭文件#include
,在assert();里面的表達(dá)式如果為真的話,assert表達(dá)式為真就什么都不會發(fā)生,如果assert的表達(dá)式為假,那么就會報(bào)錯。
在這里簡單的跟大家介紹一下const的關(guān)鍵字:const修飾的數(shù)據(jù)是常類型,常類型的變量或者對象的值是不可以被該變的,也就是被它修飾過的是常量,相比之下const常量和#define是有點(diǎn)類似的,但是在我們用數(shù)組的時候還是要區(qū)分一下,因?yàn)閿?shù)組里面 [常量表達(dá)式],此時我如果 const int n = 10 假設(shè)賦值給arr數(shù)組,int arr[n] = {0};結(jié)果是不行的,雖然加了const關(guān)鍵字,但實(shí)際上也只是變量只不過是不能被修改的變量。那么如果我們這里用的是#define—定義符號常量就可以了。??
#include#includeint My_strlen(const char* pb){ int Count = 0;//計(jì)數(shù) assert(*pb != NULL);//保證指針的有效性 NULL —— 空指針 while (*pb != "/0") { Count++; *pb++; } return Count;}int main(void){ char arr[20] = "nihao C"; int ret = My_strlen(arr); printf("arr(strlen) = %d/n", ret); return 0;}
最后,我想跟大家說程序遇到bug不要害怕,勇敢的去面對它吧,加油奧里給!
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/121140.html
摘要:調(diào)試的基本步驟發(fā)現(xiàn)程序錯誤的存在以隔離消除等方式對錯誤進(jìn)行定位確定錯誤產(chǎn)生的原因提出糾正錯誤的解決辦法對程序錯誤予以改正重新測試和版本的介紹通常稱為調(diào)試版本,它包含調(diào)試信息,并且不做任何優(yōu)化,以便于程序員調(diào)試。 ...
摘要:而就是告訴程序在那里停下來進(jìn)行單步調(diào)試,俗稱斷點(diǎn)。面向,專為異步而生的斷點(diǎn)調(diào)試功能。中的調(diào)試技巧元素的控制臺書簽開發(fā)者工具和都提供了書簽功能,用于顯示你在元素標(biāo)簽頁或標(biāo)簽頁中最后點(diǎn)擊的元素。 寫在前面本文包括瀏覽器調(diào)試,不包括web移動端調(diào)試。本文調(diào)試均在chrome瀏覽器進(jìn)行 alert 這個不用多說了,不言自明 console 基本輸出 想必大家都在用console.log在控制...
摘要:而就是告訴程序在那里停下來進(jìn)行單步調(diào)試,俗稱斷點(diǎn)。面向,專為異步而生的斷點(diǎn)調(diào)試功能。中的調(diào)試技巧元素的控制臺書簽開發(fā)者工具和都提供了書簽功能,用于顯示你在元素標(biāo)簽頁或標(biāo)簽頁中最后點(diǎn)擊的元素。 寫在前面本文包括瀏覽器調(diào)試,不包括web移動端調(diào)試。本文調(diào)試均在chrome瀏覽器進(jìn)行 alert 這個不用多說了,不言自明 console 基本輸出 想必大家都在用console.log在控制...
摘要:而就是告訴程序在那里停下來進(jìn)行單步調(diào)試,俗稱斷點(diǎn)。面向,專為異步而生的斷點(diǎn)調(diào)試功能。中的調(diào)試技巧元素的控制臺書簽開發(fā)者工具和都提供了書簽功能,用于顯示你在元素標(biāo)簽頁或標(biāo)簽頁中最后點(diǎn)擊的元素。 寫在前面本文包括瀏覽器調(diào)試,不包括web移動端調(diào)試。本文調(diào)試均在chrome瀏覽器進(jìn)行 alert 這個不用多說了,不言自明 console 基本輸出 想必大家都在用console.log在控制...
閱讀 3375·2021-11-23 09:51
閱讀 1076·2021-09-26 09:55
閱讀 4100·2021-09-22 14:58
閱讀 1767·2021-09-08 09:35
閱讀 1155·2021-08-26 14:16
閱讀 948·2019-08-23 18:17
閱讀 2177·2019-08-23 16:45
閱讀 759·2019-08-23 15:55