自从上大学接触编程以来,用过许多IDE,比如老旧的VC,还有Dev,CB,C-free之类。可除了比较老的VC的调试器外,我感觉其他IDE的调试并不好用(VS就除外了,调试器太强大了,可是你会为了不到100行的小程序去建立个VS工程?),于是我就学了gdb调试器。
gdb尽管只是一个文本界面的调试器,但功能十分强大,我是深有体会。我写这篇博客主要是为了gdb入门,但是放心,如果你是要写一个比赛代码或者百来行的小程序,这里的知识足够你用了。闲话不多说了,gdb的来源以及详细信息自行Google吧,当你对gdb有个大概了解却又完全不会用的话,仔细看看这篇博客吧。
要用gdb调试,必须先用g++编译(如果c文件gcc也可以)。下面来介绍基本的命令
l(list):显示指定行号或者指定函数附近的源代码
b(break):在指定行号或者指定函数开头处设置断点,如 b 30,就是在30行处设置断点(不要认为这样很麻烦,当你习惯以后,你会觉得鼠标真的好慢)
r(run):运行程序,直到程序结束或者断点处停下,设置断点的那一行尚未运行
c(continue):在程序中断后继续执行程序,直到程序结束或者再次遇到断点后停下。
n(next):执行一条语句,如果有函数调用,则把它直接执行完,不会进入函数内部
s(step):和n功能差不多,执行一条语句,但是如果有函数调用,则进入函数内部调试(我一般都用的是s)
u(until):执行到指定行号,我一般用这个命令来跳过循环
p(print):显示你想要看的值,那么同学不干了,我要是一直需要观察某个变量或数组的值,难道我每一步执行完都要p一下吗?嘿嘿,别急。
disp(display):基本我每次调试程序都要用到这个命令,尤其是数组内容的变化。比如你 在命令行键入 dis a 以后每一步执行完都会显示a变量的值
cl(clear):取消断点,如 cl 30 就取消了上面在三十行处的断点
i(info):显示各种信息,如 i b 显示所有断点, i disp 显示display,i lo显示左右局部变量。
好啦,先谈谈这些基本命令吧。gdb的高级功能需要我们慢慢去熟练,不想这些命令,看看敲敲就可以了。(在这里我行介绍一下bt 命令有助于我们对递归的理解)
下面我们以一个具体的例子来实际演练一番。(就拿dfs模板来练吧,顺便帮助大家理解一下dfs)
#include <cstdio> #include <cstring> #define lim 7 int Map[lim][lim], Vis[lim][lim]; char str[lim]; void dfs(int Map[][lim], int Vis[][lim], int , int ); int main() { //freopen("input.txt", "r", stdin); //freopen("output.txt", "w", stdout); int row, col,cnt; int i, j; while(scanf("%d%d", &row, &col)!=EOF) { if(row==0&&col==0) return 0; cnt=0; memset(Map, 0, sizeof(Map)); memset(Vis, 0, sizeof(Vis)); memset(str, 0, sizeof(str)); for(i=0; i<row; i++) { scanf("%s", str); for(j=0; j<col; j++) Map[i+1][j+1]=str[j]-'*'; } for(i=1; i<=row; i++) { for(j=1; j<=col; j++) if(Map[i][j]==22&&Vis[i][j]==0) { dfs(Map, Vis, i, j); cnt++; } } printf("%d\n", cnt); } return 0; } void dfs(int Map[][lim], int Vis[][lim], int row, int col) { if(Map[row][col]==0||Vis[row][col]==1) return; Vis[row][col]=1; dfs(Map, Vis, row-1, col); dfs(Map, Vis, row+1, col); dfs(Map, Vis, row, col-1); dfs(Map, Vis, row, col+1); dfs(Map, Vis, row-1, col-1); dfs(Map, Vis, row+1, col-1); dfs(Map, Vis, row-1, col+1); dfs(Map, Vis, row+1, col+1); } Microsoft Windows [版本 6.1.7601] 版权所有 (c) 2009 Microsoft Corporation。保留所有权利。 C:\Users\zhangliang>cd C:\Users\zhangliang\Desktop\acm\基础算法\搜索\dfs\油田 C:\Users\zhangliang\Desktop\acm\基础算法\搜索\dfs\油田>g++ dfs.cpp -g C:\Users\zhangliang\Desktop\acm\基础算法\搜索\dfs\油田>gdb a.exe GNU gdb (GDB) 7.5 Copyright (C) 2012 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "i686-pc-mingw32". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from C:\Users\zhangliang\Desktop\acm\基础算法\搜索\dfs\油田\a.ex e...done. (gdb) b 30 Breakpoint 1 at 0x40146a: file dfs.cpp, line 30. (gdb) r Starting program: C:\Users\zhangliang\Desktop\acm\\\dfs\\a.exe [New Thread 11044.0x3afc] 5 5 ****@ *@@*@ *@**@ @@@*@ @@**@ Breakpoint 1, main () at dfs.cpp:30 30 for(i=1; i<=row; i++) (gdb) s 32 for(j=1; j<=col; j++) (gdb) 33 if(Map[i][j]==22&&Vis[i][j]==0) (gdb) 32 for(j=1; j<=col; j++) (gdb) 33 if(Map[i][j]==22&&Vis[i][j]==0) (gdb) 32 for(j=1; j<=col; j++) (gdb) 33 if(Map[i][j]==22&&Vis[i][j]==0) (gdb) 32 for(j=1; j<=col; j++) (gdb) 33 if(Map[i][j]==22&&Vis[i][j]==0) (gdb) 32 for(j=1; j<=col; j++) (gdb) 33 if(Map[i][j]==22&&Vis[i][j]==0) (gdb) 35 dfs(Map, Vis, i, j); (gdb) dfs (Map=0x411020, Vis=0x411100, row=1, col=5) at dfs.cpp:48 48 if(Map[row][col]==0||Vis[row][col]==1) (gdb) bt #0 dfs (Map=0x411020, Vis=0x411100, row=1, col=5) at dfs.cpp:48 #1 0x004014e6 in main () at dfs.cpp:35 (gdb) s 50 Vis[row][col]=1; (gdb) s 51 dfs(Map, Vis, row-1, col); (gdb) s dfs (Map=0x411020, Vis=0x411100, row=0, col=5) at dfs.cpp:48 48 if(Map[row][col]==0||Vis[row][col]==1) (gdb) bt' #0 dfs (Map=0x411020, Vis=0x411100, row=0, col=5) at dfs.cpp:48 No locals. #1 0x00401615 in dfs (Map=0x411020, Vis=0x411100, row=1, col=5) at dfs.cpp:51 No locals. #2 0x004014e6 in main () at dfs.cpp:35 cnt = 0 i = 1 row = 5 col = 5 j = 5 (gdb) bt #0 dfs (Map=0x411020, Vis=0x411100, row=0, col=5) at dfs.cpp:48 #1 0x00401615 in dfs (Map=0x411020, Vis=0x411100, row=1, col=5) at dfs.cpp:51 #2 0x004014e6 in main () at dfs.cpp:35 (gdb) s 49 return; (gdb) s 59 } (gdb) s dfs (Map=0x411020, Vis=0x411100, row=1, col=5) at dfs.cpp:52 52 dfs(Map, Vis, row+1, col); (gdb) s dfs (Map=0x411020, Vis=0x411100, row=2, col=5) at dfs.cpp:48 48 if(Map[row][col]==0||Vis[row][col]==1) (gdb) bt #0 dfs (Map=0x411020, Vis=0x411100, row=2, col=5) at dfs.cpp:48 #1 0x00401638 in dfs (Map=0x411020, Vis=0x411100, row=1, col=5) at dfs.cpp:52 #2 0x004014e6 in main () at dfs.cpp:35 (gdb) #0 dfs (Map=0x411020, Vis=0x411100, row=2, col=5) at dfs.cpp:48 #1 0x00401638 in dfs (Map=0x411020, Vis=0x411100, row=1, col=5) at dfs.cpp:52 #2 0x004014e6 in main () at dfs.cpp:35 (gdb) s 50 Vis[row][col]=1; (gdb) s 51 dfs(Map, Vis, row-1, col); (gdb) s dfs (Map=0x411020, Vis=0x411100, row=1, col=5) at dfs.cpp:48 48 if(Map[row][col]==0||Vis[row][col]==1) (gdb) bt #0 dfs (Map=0x411020, Vis=0x411100, row=1, col=5) at dfs.cpp:48 #1 0x00401615 in dfs (Map=0x411020, Vis=0x411100, row=2, col=5) at dfs.cpp:51 #2 0x00401638 in dfs (Map=0x411020, Vis=0x411100, row=1, col=5) at dfs.cpp:52 #3 0x004014e6 in main () at dfs.cpp:35 (gdb) q A debugging session is active. Inferior 1 [process 11044] will be killed. Quit anyway? (y or n) y
以上为在控制台下调试dfs模板的部分内容,读者可以自己尝试,多尝试尝试就熟练了