C++介绍以及编译执行和调试
C++的介绍
C++,实际上是另一种语言的衍生版本,它就是C,而这个语言在研发初期的名字叫做“带类的C”,那么很显然这个语言的一大特色就在于它具有class。C++是一种面向对象的程序设计语言,在基本所有的系统中都可以运行。
C的一大特点就是高性能,它的速度基本是所有高级语言中最快的,因此为了保证速度,C++语言都是编译型的。这也是它为什么可以成为算法竞赛的主流语言的原因。
C++的编译和执行
关于编译执行C++程序,由于国内的算法竞赛在NOIP(目前已经成为CSP)默认使用的IDE都是Dev-C++,因此笔者就权当读者们的电脑上已经配置好了相关程序。
接下来,在代码框内打出如下代码,按下F11便可以进行编译和执行了!
1 |
|
当然,在这里我们要为大家讲解的并不只是一个简单的F11而已。读者要清楚C++文件的编译依靠的是G++,是属于GNU的编译器,而在一般情况下G++编译文件有以下几步:
- 预处理生成后缀名为.i的文件
- 转换为汇编语言.s
- 转换为目标代码.o
- 连接目标代码,生成可执行程序.exe
那么接下来我们就尝试在命令行里面执行这些操作。
按下Win + R输入cmd即可进入命令指示符,然后我们通过cd命令进入保存好的代码源文件所在的文件夹。
然后我们输入以下指令
> g++ code.cpp -o code.exe
注意,在这个地方如果我们的代码有错误,那么是会出现问题的。
比如我们的代码在最后去掉了return 0 的分号:
1 |
|
那么运行这个命令的时候就会出现以下情况:
这时G++就提醒我们,在第6行出现了错误:没有加“;”。
然后在保证没有错误的情况下,我们执行以下命令就可以运行这个程序了。
> code.exe
而如果我们不加-o code.exe的话那么给出的文件将是默认的a.exe,而运行这个a.exe也是可以得出正确的结果的。
这个-o是什么意思呢,它可以让我们自定义输入文件名和输出文件名。当然并不是指的你的源代码的程序输入和输出,而是指的g++的输入和输出,对于上面的code.cpp来说,如果不加-o那么就相当于是输入了code.cpp文件,然后输出了a.exe文件,而如果我们加了-o就可以是g++输出code.cpp文件。
源代码的调试
对于调试,很多人都是直接使用的Dev-C++的内置调试,但是经常会出现错误,因此在命令行里面进行调试也是很不错的选择。
为了充分解释各种命令,我们写了一个较为复杂的程序。
1 |
|
想必大家也都能看懂这个程序,笔者不再解释。我们把它保存为code2.cpp
接下来我们在命令行里面输入如下指令:
> g++ code2.cpp -g -o code2.exe
可以发现这个指令比之前多了一个-g,它可以使我们的g++输出调试信息。
> gdb code2.exe
这样我们便可以调试这个程序了。
接下来如果我们直接输入run指令,那么程序会直接执行到底,与不调试没有什么不同。
因此和Dev-c++一样,我们一开始也要先设置断点。在这里你可以设置第几行,也可以直接写函数名称。而设置断点的指令叫做b
(gdb) b main
于是你发现现在程序直接执行到了main函数的第一行。按下n指令我们可以向后进行。
因为接下来我们要输入,所以输入完毕后程序才到了下一行。
直接回车是执行上一次的指令,那么我们直接回车程序便会向后执行。
可以发现现在执行到了要进入函数的这一行。先等一等,我们输入p后面跟变量名称可以查看现在的变量的数值。
没有什么问题我们就想继续进行了。但是这里不能直接n了,直接n我们会直接跳过了这个函数的执行部分,这个时候如果我们想进入函数,要输入s
成功进入了函数,但是现在我们遇到了一个循环结构,那么如果我们想时时刻刻查看Z的数值,不用每一次都p,我们只需要display Z 就可以将Z设为默认查看变量,每一次程序往下执行都会显示。
可以发现每一次继续执行都会显示出Z的大小。那么如果我们不需要查看Z了,我们需要undisplay 1,其中1是gdb给Z的编号。
此时GDB便不会再一直显示Z的大小了。
最后,输入q我们便可以推出gdb回到命令行了。
下面是一些GDB能够用到的基本操作,给大家列出来以方便使用
命令 | 命令缩写 | 作用 |
---|---|---|
list | l | 显示当前行或指定行附近的多行代码 |
break | b | 设置断点到指定行 |
info | i | 描述程序当前状态 |
run | r | 开始执行程序 |
display | disp | 默认显示某个变量的数值 |
step | s | 进入函数 |
next | n | 继续执行 |
p | 查看一次变量的当前数值 | |
continue | c | 运行到下一个断点 |
start | st | 开始执行程序到main函数 |
kill | k | 终止正在执行的程序 |
backtrace | bt | 查看堆栈信息 |
watch | 监视变量变化(在变量数值发生变化时停止继续执行) | |
set var name = value | 改变变量name的值value | |
quit | q | 退出GDB |