GDB 基本命令与功能
作为一个初学者,看见GDB有如下的功能觉得比较抽象和难以领悟其功能具体作用,于是我通过一段BFS来初探GDB,于是就有这篇博客啦!
代码实例
博主在这里采用无参运行的方式(因为有参运行出现了一些错误 😦 )
题目如下:
洛谷1135
#include<queue>
#include<vector>
using namespace std;
int bfs(vector<int>& set, int s, int e) {
vector<bool> vis(set.size(), false);
queue<pair<int, int>> q;
q.push({s, 0});
while (!q.empty()) {
int curr = q.front().first;
int count = q.front().second;
q.pop();
queue<pair<int, int>> temp = q;
while (!temp.empty()) {
cout << "(" << temp.front().first << ", " << temp.front().second << ") ";
temp.pop();
}
cout << endl;
if (curr == e) return count;
for (int i = -1; i <= 1; i += 2) {
int next = curr + set[curr] * i;
if (next > 0 && next < set.size() && !vis[next]) {
vis[next] = true;
q.push({next, count + 1});
}
}
}
return -1;
}
int main() {
int N, A, B, res;
// 将输入硬编码
N = 5;
A = 1;
B = 5;
vector<int> set = {0, 3, 3, 1, 2, 5};
res = bfs(set, A, B);
cout << (res == 0 ? 0 : res);
return 0;
}
编译准备并加载GDB
首先我们得保证运行的文件是可执行文件!
通过下图命令,我们不仅能生成可执行文件也能做好编译准备 ( -g )
启动
一开始博主是打算在运行的时候传入参数,但是刚开始出现了如下错误,发现是不能直接键入值的应该前面加一个run,再就是觉得传参稍显麻烦就将代码修改了一下变成了无参运行
(gdb --args test 5 1 5 #加载前设置
(gdb) set args 5 1 5 #运行前设置
(gdb) run 5 1 5 #运行时设置
设置断点
有两种设置断点方式
同时,在设置断点后可以通过两种方式来查看变量,一种是在到了断点后print变量显示,一种是在设置断点时通过command命令
其中>continue 也可以换成其他命令,比如>next 等,根据需要设置
并且若觉得断点不必要可以删除,但貌似删除后编号还是保留的
这是博主设置的断点位置
运行程序
输入run 即可开始运行
此时根据断点展示参数,其中一种会自动展示(即在设置断点时通过command命令)另一种则在来到断点后输入print
通过代码知,想从1层到5层(电梯每层上下升层数为3 3 1 2 5)需要先从1层到4层,再从4层到2层,再到5层,需要按3次电梯,这个数值设置使得负数层和超过最大层的楼层没有push进队列q里,体现BFS的特点,但vis的作用没怎么凸显,其中vis是防止程序陷入死循环,读者可以思考一下传入的参数去验证这个程序是否能避免死循环。
当输出结果3时程序已经不再运行,再输入continue显示
The program is not being run
此时按ctrl+c退出即可