C++介绍以及编译执行和调试

C++介绍以及编译执行和调试

C++的介绍

C++,实际上是另一种语言的衍生版本,它就是C,而这个语言在研发初期的名字叫做“带类的C”,那么很显然这个语言的一大特色就在于它具有class。C++是一种面向对象的程序设计语言,在基本所有的系统中都可以运行。

C的一大特点就是高性能,它的速度基本是所有高级语言中最快的,因此为了保证速度,C++语言都是编译型的。这也是它为什么可以成为算法竞赛的主流语言的原因。

C++的编译和执行

关于编译执行C++程序,由于国内的算法竞赛在NOIP(目前已经成为CSP)默认使用的IDE都是Dev-C++,因此笔者就权当读者们的电脑上已经配置好了相关程序。

接下来,在代码框内打出如下代码,按下F11便可以进行编译和执行了!

1
2
3
4
5
6
#include <iostream>
using namespace std ;
int main() {
cout << "Hello World !" << endl ;
return 0 ;
}

当然,在这里我们要为大家讲解的并不只是一个简单的F11而已。读者要清楚C++文件的编译依靠的是G++,是属于GNU的编译器,而在一般情况下G++编译文件有以下几步:

  1. 预处理生成后缀名为.i的文件
  2. 转换为汇编语言.s
  3. 转换为目标代码.o
  4. 连接目标代码,生成可执行程序.exe

那么接下来我们就尝试在命令行里面执行这些操作。

按下Win + R输入cmd即可进入命令指示符,然后我们通过cd命令进入保存好的代码源文件所在的文件夹。

EnterFolder

然后我们输入以下指令

> g++ code.cpp -o code.exe

G++1

注意,在这个地方如果我们的代码有错误,那么是会出现问题的。

比如我们的代码在最后去掉了return 0 的分号:

1
2
3
4
5
6
#include <iostream>
using namespace std ;
int main() {
cout << "Hello World !" << endl ;
return 0
}

那么运行这个命令的时候就会出现以下情况:

G++2

这时G++就提醒我们,在第6行出现了错误:没有加“;”。

然后在保证没有错误的情况下,我们执行以下命令就可以运行这个程序了。

> code.exe

G++4

而如果我们不加-o code.exe的话那么给出的文件将是默认的a.exe,而运行这个a.exe也是可以得出正确的结果的。

G++5

这个-o是什么意思呢,它可以让我们自定义输入文件名和输出文件名。当然并不是指的你的源代码的程序输入和输出,而是指的g++的输入和输出,对于上面的code.cpp来说,如果不加-o那么就相当于是输入了code.cpp文件,然后输出了a.exe文件,而如果我们加了-o就可以是g++输出code.cpp文件。

源代码的调试

对于调试,很多人都是直接使用的Dev-C++的内置调试,但是经常会出现错误,因此在命令行里面进行调试也是很不错的选择。

为了充分解释各种命令,我们写了一个较为复杂的程序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std ;
int X, Y, Z ;
const int N = 5 ;
int Solve(int A, int B) {
for (int i = 1 ; i <= N ; i ++)
Z = X * X + Y * Y ;
return Z ;
}
int main() {
cin >> X >> Y ;
X = X * 2 ;
Y = Y / 2 ;
Solve(X, Y) ;
Z = Z + 1 ;
cout << Z << endl ;
return 0 ;
}

想必大家也都能看懂这个程序,笔者不再解释。我们把它保存为code2.cpp

接下来我们在命令行里面输入如下指令:

> g++ code2.cpp -g -o code2.exe

可以发现这个指令比之前多了一个-g,它可以使我们的g++输出调试信息。

> gdb code2.exe

这样我们便可以调试这个程序了。

GDB

接下来如果我们直接输入run指令,那么程序会直接执行到底,与不调试没有什么不同。

GDB2

因此和Dev-c++一样,我们一开始也要先设置断点。在这里你可以设置第几行,也可以直接写函数名称。而设置断点的指令叫做b

(gdb) b main

GDB3

于是你发现现在程序直接执行到了main函数的第一行。按下n指令我们可以向后进行。

GDB5

因为接下来我们要输入,所以输入完毕后程序才到了下一行。

直接回车是执行上一次的指令,那么我们直接回车程序便会向后执行。

GDB6

可以发现现在执行到了要进入函数的这一行。先等一等,我们输入p后面跟变量名称可以查看现在的变量的数值。

GDB7

没有什么问题我们就想继续进行了。但是这里不能直接n了,直接n我们会直接跳过了这个函数的执行部分,这个时候如果我们想进入函数,要输入s

GDB7

成功进入了函数,但是现在我们遇到了一个循环结构,那么如果我们想时时刻刻查看Z的数值,不用每一次都p,我们只需要display Z 就可以将Z设为默认查看变量,每一次程序往下执行都会显示。

GDB8

可以发现每一次继续执行都会显示出Z的大小。那么如果我们不需要查看Z了,我们需要undisplay 1,其中1是gdb给Z的编号。

GDB9

此时GDB便不会再一直显示Z的大小了。

最后,输入q我们便可以推出gdb回到命令行了。

下面是一些GDB能够用到的基本操作,给大家列出来以方便使用

命令 命令缩写 作用
list l 显示当前行或指定行附近的多行代码
break b 设置断点到指定行
info i 描述程序当前状态
run r 开始执行程序
display disp 默认显示某个变量的数值
step s 进入函数
next n 继续执行
print p 查看一次变量的当前数值
continue c 运行到下一个断点
start st 开始执行程序到main函数
kill k 终止正在执行的程序
backtrace bt 查看堆栈信息
watch 监视变量变化(在变量数值发生变化时停止继续执行)
set var name = value 改变变量name的值value
quit q 退出GDB

本文标题:C++介绍以及编译执行和调试

文章作者:Sue Shallow

发布时间:2019年11月11日 - 22:16:31

最后更新:2019年11月11日 - 19:52:30

原始链接:http://Yeasion.github.io/2019/11/11/C++介绍以及编译执行和调试/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。