算法笔记0.附录(编译器和调试器)
A.3编译器和调试器
gcc安装和测试:
推荐MinGW环境下的gcc,和Linux下的gcc一致性较好。在www.mingw. org(或http://www.mingw-w64.org)下载安装包,安装时选择g++编译器
(下载参考https://tieba.baidu.com/p/5487544851?red_tag=0273754968&traceid=)
安装后再命令行执行gcc命令,如果显示gcc:no input files则按照成功,如果没有,则设置环境变量加入bin目录
若已经安装了devcpp,可能已经含有mingw(D:\Program Files (x86)\Dev-Cpp\MinGW64)
常见编译选项:
测试test.cpp
#include<stdio.h> main()//没有int { int a,b; scanf("%d%d",&a,&b); int c=a+b;//c没有在开头定义 printf("%d%d\n",c);//多一个占位符 }//没有返回值 |
在命令行gcc test.cpp,程序没有输出,目录下多出可执行文件a.exe
gcc test.cpp -o test(可执行文件名为test)编译后可以用test(Linux为./test)运行程序
让编译显示警告:gcc test.cpp -o test -Wall
编译器警告了这三个问题 test.cpp: In function 'int main()': test.cpp:7:19: warning: format '%d' expects a matching 'int' argument [-Wformat=] printf("%d%d\n",c); |
进一步用-ansi-pedantic检擦代码是否符合ANSI C标准(只能检查.c文件,无法检查.cpp文件)
gcc test.c -o test -Wall -ansi -pedantic
test.c: In function 'main': test.c:6:2: warning: ISO C90 forbids mixed declarations and code [-Wpedantic] int c=a+b;//c没有在开头定义 ^ test.c:6:6: warning: unused variable 'c' [-Wunused-variable] int c=a+b; ^ |
-lm能让编译器连接数学库允许使用math.h中函数,c++会自动连接(扩展名.cpp)
-DDEBUG在编译时定义符号DEBUG,也可以换成其他的(如LOCAL)这样#ifdef DEBUG到#endif中间的语句会被编译,否则其中不会被编译
-O1 -O2和-O3可对代码进行速度优化
gdb简介:
gdb要和gcc配合使用
编译时加-g生成调试用的符号表(gcc test.cpp -o test -Wall -g)
编译成exe后,执行gdb test.exe
显示: Reading symbols from test.exe...done. 从 test. exe 中读取符号 |
使用l命令能看到源程序(L不是1)
l 15,会显示第15行以及前后若干行。
l main显示main函数开头的附近15行
l显示下10行,list -显示上10行。
所有命令可以用help list查看(gdb中的命令可以用前几个字母简写,list写成l)
运行程序的命令是r(run),设置断点b(break),c(continue)继续运行,n(next)和s(step)逐条执行(next把函数当作一行,step进入函数内部),Enter键等价于执行上一条指令:
b main在main的开头设置断点,也用行号设置断点。
可以用b main和r开头调试程序
u(until)执行到指定位置,p(print)打印变量值,i lo(info locals)显示所有局部变量:
u doit执行到doit函数的开头,此时可打印函数值
disp(display)和n/s/u等单步执行指令配合使用:
i disp(info display)列出所有display,
删除/禁止/恢复display:d(delete)/ dis(disable)/en(enable) disp (dislay)
类似根据断点编号删除/禁止/恢复断点,或cl(clear)根据行号或函数名删除
gdb的高级功能:
栈帧相关命令(通过help stack查看):
bt
comm(commands)指定在某个断点处停下来后执行gdb命令,
ig(ignore)让断点在前count次不停,
cond(condition)给断点加条件:cond 2(断点编号) i==5(断点条件)
watch特殊断点:
watch a(wa a)在a被修改时停下,并显示修改前后的变量值,
awatch(aw)每次被修改都停下
rwatch(rw)在变量被读时停下
call可以像在代码中一样自由调度源程序函数:
call mysort(a,a+10)
如果是STL中函数(sort)可能需要在源程序中打包:
void mysort(int*p,int*q){ sort(p,q); } |
print,condition,display也可以这样使用函数:
如p rand()输出随机数,
condition编写一个返回bool的函数专门作为断点条件
尽量使用输出中间变量,直觉,经验调试,不用gdb