Biu一Biu--GDB
gcc常見編譯選項
- ** -c **:只啟用預處理、編譯和彙編,也就是生成obj檔案
- ** -S **:只啟用處理和編譯,把檔案編譯成彙編程式碼
- ** -o **:定製目標名稱,預設的時候編譯出來的可執行程式名為a.exe(windows)或a.out(linux)
- ** -Wall **:開啟一些很有用的編譯警告
- ** -std **:指定C標準,如-std=99,使用C99標準
- ** -g **:指示編譯器,編譯的時候新增除錯資訊
- ** -O0 -O1 -O2 -O3 **:編譯器的優化選項的4個級別,-O0表示沒有優化,-O1為預設值,-O3優化級別最高
/*
file_name: swap.c
*/
#include<stdio.h>
void swap(int a, int b)
{
int t;
t = a;
a = b;
b = t;
}
int main()
{
int a=3, b=4;
swap(a,b);
printf("%d %d",a,b);
return 0;
}
GDB的使用
什麼是GDBhttps://www.bing.com/knows/search?q=gdb&mkt=zh-cn&FORM=BKACAI
http://www.gnu.org/software/gdb/
一般來說,GDB主要幫助你完成以下四個方面的內容
1、啟動你的程式,可以按照你的自定義的要求隨心所欲的執行程式
2、可以讓被除錯的程式在你所指定的調置的斷點處停住。(斷點可以是條件表示式)
3、當程式被停住時,可以檢查此時你的程式中所發生的事
4、你可以改變你的程式,將一個BUG產生的影響修正,從而測試其他BUG
GDB常見命令
簡稱 | 全稱 | 備註 |
---|---|---|
l | list | 顯示指定行號或者指定函式附近的原始碼 |
b | break | 在指定行號或指定函式開頭設定斷點 |
r | run | 執行程式,直到程式結束或遇到斷點 |
c | continue | 在程式中斷後繼續執行程式,直到程式結束或遇到斷點停下。注意在程式開始執行前只能用r,而不能用c |
n | next | 執行一條語句。如果有函式呼叫,則把它當做一個整體 |
s | step | 執行一條語句。如果有函式呼叫,則進入函式內部 |
u | until | 執行到指定行號或指定函式的開頭 |
p | 顯示變數或表示式的值 | |
disp | display | 把一個表示式設定為display,當程式每次停下來時都會顯示其值 |
cl | clear | 取消斷點,和b格式相同,如果該位置有多個斷點,將同時取消 |
i | info | 顯示各種資訊,如i b顯示所有斷點,i disp顯示display,而i lo顯示所有區域性變數 |
bt | backtrace | 列印所有棧幀資訊 |
呼叫棧(Call Stack)
呼叫棧描述的是函式之間的呼叫關係。呼叫棧由棧幀(Stack Frame)組成,每個棧幀對應著一個未執行完的函式。在GDB中可以用backtrace(簡稱bt)命令列印所有棧幀資訊。若要用p命令列印一個非當前棧幀的區域性變數,可以用frame命令選擇另一個棧幀
拿個程式來玩玩,swap.c檔案
#include<stdio.h>
void swap(int a, int b){
int t;t = a;a = b;b = t;
}
int main(){
int a=3, b=4;
swap(a,b);
printf("%d %d",a,b);
return 0;
}
*** 程式的目的是交換a和b的值,然而並沒有交換交換成功 ***
原因:
- 函式的形參和在函式內部宣告的變數都是該函式的區域性變數。無法訪問其他函式的區域性變數。
- 區域性變數的儲存空間是臨時分配的,函式執行完畢時,區域性變數的空間將被釋放,其中的值無法保留到下次使用。
- 如果要實現真正的交換,我們應該傳入的是儲存變數的地址,此時函式swap的形參型別應該為指標型別
PS:
C語言的變數都是放在記憶體中的,而記憶體中間的每一個位元組都有一個稱為地址(address)的編號。
每一個變數都佔有一定數目的位元組(可以用sizeof運算子獲得),其中第一個位元組的地址稱為變數的地址。
o(*≧▽≦)ツ┏━┓拿個遞迴程式來玩玩
#include<stdio.h>
int f(int n)
{
return n == 0 ? 1 : f(n-1)*n;
}
int main()
{
printf("%d\n",f(3));
return 0;
}
在C語言的函式中,呼叫自己和呼叫其他函式沒有任何本質區別,都是建立新棧幀,傳遞引數並修改當前程式碼行。在函式執行體完畢後刪除棧幀,處理返回值,並修改當前程式碼行數。
以上呼叫棧的一個比喻
皇帝(擁有main函式的棧幀):大臣,你給我算下f(3)
大臣(擁有f(3)的棧幀):知府,你給我算下f(2)
知府(擁有f(2)的棧幀):縣令,你給我算下f(1)
縣令(擁有f(1)的棧幀):師爺,你給我算下f(0)
師爺(擁有f(0)的棧幀):回老爺,f(0)=1
縣令(心算f(1)=f(0)1=1):回知府大人,f(1)=1
知府(心算f(2)=f(1)2=2):回大人,f(2)=2
大臣(心算f(3)=f(2)*3=6):回皇上,f(3)=6
皇上滿意了
emmmmmm。。。。。。。。。。。。
最後歡迎來我的個人部落格看看https://shansan.top