您的位置:首页 > 其它

g++与gdb学习笔记(针对NOI)

2016-02-09 22:36 239 查看
由于时间有限,在奥赛上往往要秉承实用至上的原则。个人用Windows下的Dev C++非常习惯,本来不

想去研究g++和gdb的,但考虑到不能老依赖GUI,而且NOI Linux下的Anjuta用起来感觉怪怪的,且GUIDE界面实在感人,所以就决定去研究g++和gdb,准备用gedit、g++、gdb组合实现代码。

g++

1、g++编译命令: g++ test.cpp

该命令会生成一个a.exe(Windows)或a.out(Linux)

2、编译选项:可以用-o(小写)来指定文件名

如:g++ test.cpp -o test

会生成一个test.exe(Windows)或test(Linux)

3、其它编译选项:

这里只列举几个比较常用的选项

-O2 编译优化开关之一,编译出来的程序运行速度-O2 > -O1 > 缺省,注意不同的编译优化开关对代码的“理解”方式可能不同,所以对一些规范性不是那么高的代码,不同编译开关编译出来的程序甚至可能运行起来完全不同!考试一般是不加编译开关的。

-Wall 这个是打开警告,在会对一些不是特别规范的代码发出警告

下面是一个示例:

#include <cstdio>
using namespace std;
int main () {
int n=1,m;
if (n=1) printf("Equal");
}


在输入 g++ test.cpp -o test -Wall 并执行后,g++给出了下面两个警告:

test.cpp: In function ‘int main()’:

test.cpp:5:9: warning: suggest parentheses around assignment used as truth value [-Wparentheses]

if (n=1) printf(“Equal”);

^

test.cpp:4:10: warning: unused variable ‘m’ [-Wunused-variable]

int n=1,m;

^

第一个警告是针对n=1的,n=1在作为判断条件时是合法的,返回值一定是1,但它显然不正确;第二个警告是说有一个变量m没有使用

-g 生成调试时所用的符号表,如果要用gdb调试,这个选项要加上

gdb

gdb作为一个文本界面的调试器,看起来确实不太友好。。。但是不得不承认,它和许多看起来一样不友好的命令行界面程序一样,功能比GUI的程序要强大。出于实用,这里只介绍其基本用法。但是,相对于调试,我个人更建议用在程序中输出中间变量的方法 ,能够锻炼代码实现能力

在g++ 加上-g编译选项编译程序之后,直接输入gdb test(针对linux),进入gdb调试,下面是一些gdb环境下的指令

1、l list的缩写,这个命令可以在屏幕上打印部分源程序。连续执行,可以打印全部程序源代码。它还可以加参数,比如l 14会打印14行前后的部分源代码,l main会打印main函数附近的源代码。

2、b break的缩写,添加断点,b 14代表在14行添加断点,b main代表在int main ()这一行上打上断点

3、r run的缩写,执行程序

4、c continue的缩写,执行到下一个断点,注意:gdb中直接敲回车会默认为调用上一条命令,所以可以输入c然后,下面就可以只按回车了

5、n next的缩写,执行下一行

6、s step的缩写,执行下一步,注意:它和n的区别:n遇到函数调用,会在外面跳过去,而s则会跳转到函数体里面,如果某函数是位于某头文件里面的,就真的会跳转到那个头文件里面。。。

注意:以上三个命令每执行一次就会打印一次“当前代码行”

7、p print的缩写,用来显示变量或表达式的值,p a可以显示变量a的值,我非常喜欢的一点,就是它可以直接显示一整个数组或结构体的值如果a是数组或一个结构体,也可以用p a效果可以自己试一下

7、disp display的缩写可以把某一个变量或表达式设为display,每当程序停下来时就会显示其值,但是有一个鲠,看一下下面的例子

#include <cstdio>
using namespace std;
int test () {
int n;
}
int main () {
int n=1,m;
if (n=1) printf("Equal");
}


这个程序,当“当前代码行”移动到test函数内部的时候输入display n,来显示n的值,但这个操作只会在进入test函数的时候才奏效,如果进入的是main,则main的n不会被显示

设置好了断点和display,那怎么把它们删除呢?

用i b (i是info的缩写)来显示所有的断点信息,其中有断点的编号也有断点所在的行号。输入d 2来删掉2号断点(d是delete的缩写),也可以dis 2来暂时禁用2号断点(dis是disable的缩写),用en 2来恢复第二个断点。也可以根据行号删除断点,cl 14就是删除第14行的所有断点

用i disp来显示所有的display,用d disp 2,dis disp 2,en disp 2分别来删除、临时禁用、恢复第二个display

i实际还有一个非常实用的用法:i lo可以打印所有当前局域变量的值

9、bt可以打印所有帧栈,这个在研究递归和函数调用的时候非常有用,使用up进入调用的上一个帧栈,down进入调用的下一个帧栈
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: