<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
bug意為臭蟲,計算機術語裡就是么蛾子,對,你的程式又出么蛾子了。為什麼要叫bug?關於這個還有段有趣的歷史
有一天赫柏正愉快地敲著Mark Ⅱ的程式碼時,計算機突然就停止運作了,那時的計算機遠不如現在小巧,赫柏他們只能一個個排查計算機龐大的處理器群,經過一段時間的排查後停機原因終於被找到了。原來是一隻飛蛾被計算機的光和熱吸引,觸發了電腦的短路,當然這隻可憐的飛蛾也一命嗚呼了按理說一般人也就是把飛蛾拿走,然後重啟下電腦也就完事了,但赫柏顯然不是一般人她小心翼翼地把這隻飛蛾拿了下來,然後把它工工整整地粘在了記事本上… …
這就是歷史上第一個 bug 的誕生。
我估計前期我們找 bug 都是用眼睛瞅,特別是我們這種大一的剛接觸的,現在還好,到了以後需要寫大工程的時候,眼瞅不頭疼的才是大哥,對於一個成熟程式設計師20%時間寫程式碼而80%時間在偵錯程式碼。
我們寫程式碼就是一個推理的過程,整個流程的正確與錯誤都是有跡可循的,推理的途徑就是這些跡象。
一名優秀的程式設計師就是一個優秀的偵探,找到跡象,順流而下是錯誤,順流而上是真相,偵錯就是我們破案的過程。
1.找錯(進行隔離,消除來定位錯誤)
2.知道錯因
3.尋找解決辦法
4.糾正,重測
Debug(Debugging),即排錯,稱為偵錯版本,不作任何優化,包含偵錯資訊,便於我們偵錯程式。
Release ,即釋放,成為測試版本,往往進行各種優化,讓程式碼在大小和執行速度上都是最優的,面向使用者,可以很好的使用。但是!注意Release版本是沒法進行偵錯的,這種觀點僅限於我當前知識面的限制,實際上Release也是可以的,下面是大佬對我的指正意見:
在偵錯過程中,掌握一些快捷鍵會大大增加我們的效率。以vs2019為例,我們先會設定斷點如圖(行標左側設定)
斷點設定在需檢查程式碼的任意位置,執行到這一步就會停下給我們報告。斷點完F5偵錯,執行視窗彈出後就會發現偵錯就會出現更多內容,我框出來的在之前記錄C語言學習時都有用到。
注意F5是偵錯,Ctrl+F5是執行,通常會使用會F5跳到想要的斷點處,有些電腦上比較裝怪,快捷鍵沒反應的,建議多按一個Fn鍵試試,Fn是功能輔助鍵,相當於一個開關,本質上 F5+Fn = F5。需要強調的是逐語句和逐過程,如果你想看每個細節,不放過每一個角落就用逐語句,兩者的力度是不一樣的,逐過程會跳過程式碼裡的函數部分。
vs玩家重點推薦 Ctrl+k+c,註釋選中行;Ctrl+k+u,取消註釋,熟練運用會很方便。
其餘還有很多不贅述,下面準備了超全的實用快捷鍵用法:
除了用偵錯驗證程式碼的正確性,還可以用於研究具體的問題,舉個栗子:
這道題是Nice的面試真題
請說明下面程式碼是否能正常運?執行結果是什麼?為什麼會出現這個結果?
int main() { int i = 0; int arr[10] = { 0 }; for (i = 0; i <= 12; i++) { arr[i] = 0; printf(「hehen」); } return 0; }
這裡當我們開啟偵錯視窗直接開調:
很直觀的可以發現,哦,原來是i與arr[12]相同,我們發現在arr[12]改變時i第的值也會隨之改變,那我就直接取出他們都地址看一看是不是一樣的。
OMG,是一樣的。但我們這裡的偵錯只能看到現象,他底層的原理我們要自己思考。
其死迴圈的邏輯大致是這樣的,我們建立了一個變數i,arr,他們都是區域性變數,而區域性變數時放在棧上的,棧區上記憶體使用習慣是先使用高地址儲存空間,再使用低地址。這裡注意,我們開始給的十個大小的空間,i的變數是到12,這裡明顯是越界存取,但為什麼沒有報錯停下來?結合我們剛剛監視的結果,我們再把格局開啟:
陣列隨著下標的增長,地址是由低到高的變化,在我陣列適當越界時,如果i和arr之間的空間適當的話,就有可能使arr向後越界時就存取到了i,造成了迴圈變數的i改變,最終會死迴圈。
這種錯誤其實存在偶然性,首先i和arr[12]相同,只是恰巧,但如果我把i換成11,結果就大相徑庭了,我只形成了越界但沒有改變回圈變數i的值。其次,這個程式碼是嚴重依賴環境的,比如在VC 6.0裡面i和arr就是連續的,gcc裡面i和arr之間有一個空間。
打趣的是,我們在Release版本里面是不會報錯並且會停下來,其實在剛剛的截圖裡面也是會報錯的,但是!死迴圈停不下來,他根本沒時間來報錯。Rlease的優化並不是萬能的,不要期待利用Release版本來掩蓋程式碼的bug,最好的做法就是不要越界。
1.硬性要求執行正常
2.bug少(估計沒人敢保證零bug吧)
3.效率高
4.可讀性高
5.可維護性(容易修改與二創)
6.註釋(方便閱讀)
7.檔案齊全
1.使用assert
意為斷言,在程式碼執行前設的前哨,比如我們函數傳參時,當我傳的內容變成空指標,後面如果函數進行解除參照操作,對於空指標解除參照是會造成程式崩潰的,是很危險的,所以我們用assert當監護人能快一步該訴我們問題在這裡;設定assert也是一個好習慣,面試官見了直呼老司機!
# include<assert.h> void my_str(char* a, char* b) { assert(a != NULL && b != NULL);//斷言 while (*b != ' ') { *a = *b; b++; a++; } *a = *b; } int main() { char arr[10] = {0}; char arr2[] = "bit"; my_str(NULL, arr2); // 故意設成NULL程式會崩潰 printf("%sn", arr); return 0; }
效果如上圖就會顯示斷言失敗。
2.儘量使用const
const常變數修飾符。
就上面模擬strcpy函數,如果有天有個內鬼改了你的程式碼,寫成 *b = *a,就拷反了,編譯器也會傻不拉嘰的輸出,儘管結果什麼都沒有。那怎麼辦呢?我在開頭就定義好
char* my_str(const char *a,const char* b)
這樣不管你咋改,我 *a,*b都是無法改變的。
注意const int *p=&a , const 在 * 左邊時,修飾的是指標指向的內容,指標變數不影響 ;在 * 右邊是,修飾指標本身,指標變數不能修改,其內容可以通過指標來改變。
3,形成良好的編碼風格
4.註釋!註釋!註釋!(好習慣講三次)
5.避免編碼陷阱
今天就到這裡了,摸了家人們,更多關於Debug與Release偵錯技巧的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45