程序调试
程序调试是一个程序员必备的能力和技巧,在肉眼难以观察出程序漏洞时,调试是一种较为有效的协助方式。
调试的基本过程
- 设置断点: 好的断点设置可以减少调试的时间
- 设置察看量: 察看变量的值以确认逻辑
- 逐步运行语句 查看每一条语句是否存在Bug
- 确定错误位置: 通过逐条查看得出结论
Qt调试举例
下面是帮同学调试过的一个程序
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "model.h"
#include<QString>
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_clearButton_clicked();
void on_button0_clicked();
void on_equalButton_clicked();
void on_button1_clicked();
void on_button2_clicked();
void on_button3_clicked();
void on_subButton_clicked();
void on_button4_clicked();
void on_button5_clicked();
void on_button6_clicked();
void on_button7_clicked();
void on_button8_clicked();
void on_button9_clicked();
void on_addButton_clicked();
void on_mulButton_clicked();
void on_divButton_clicked();
private:
Ui::MainWindow *ui;
QString str;
Model *model ;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "model.h"
#include<cstdio>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->addButton->setText(tr("+"));
ui->divButton->setText(tr("/"));
ui->equalButton->setToolTip(tr("="));
ui->mulButton->setText(tr("*"));
ui->subButton->setText(tr("-"));
ui->clearButton->setText(tr("C"));
ui->button0->setText(tr("0"));
ui->button1->setText(tr("1"));
ui->button2->setText(tr("2"));
ui->button3->setText(tr("3"));
ui->button4->setText(tr("4"));
ui->button5->setText(tr("5"));
ui->button6->setText(tr("6"));
ui->button7->setText(tr("7"));
ui->button8->setText(tr("8"));
ui->button9->setText(tr("9"));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_clearButton_clicked()
{
str = "";
ui->label->setText("str");
}
void MainWindow::on_button0_clicked()
{
if(str!=""){
str += "0";
ui->label->setText(str);
}
}
void MainWindow::on_button1_clicked()
{
str += "1";
ui->label->setText(str);
}
void MainWindow::on_button2_clicked()
{
str += "2";
ui->label->setText(str);
}
void MainWindow::on_button3_clicked()
{
str += "3";
ui->label->setText(str);
}
void MainWindow::on_button4_clicked()
{
str += "4";
ui->label->setText(str);
}
void MainWindow::on_button5_clicked()
{
str += "5";
ui->label->setText(str);
}
void MainWindow::on_button6_clicked()
{
str += "6";
ui->label->setText(str);
}
void MainWindow::on_button7_clicked()
{
str += "7";
ui->label->setText(str);
}
void MainWindow::on_button8_clicked()
{
str += "8";
ui->label->setText(str);
}
void MainWindow::on_button9_clicked()
{
str += "9";
ui->label->setText(str);
}
void MainWindow::on_subButton_clicked()
{
int num = str.toInt();
model->setNum1(num);
str = "";
QString s = ui->subButton->text();
ui->label->setText(s);
model->setFlag("-");
}
void MainWindow::on_addButton_clicked()
{
int num = str.toInt();
model->setNum1(num);
str = "";
QString s = ui->addButton->text();
ui->label->setText(s);
model->setFlag("+");
}
void MainWindow::on_mulButton_clicked()
{
int num = str.toInt();
model->setNum1(num);
str = "";
QString s =this->ui->mulButton->text();
ui->label->setText(s);
model->setFlag(s);
}
void MainWindow::on_divButton_clicked()
{
int num = str.toInt();
model->setNum1(num);
str = "";
QString s = ui->divButton->text();
ui->label->setText(s);
model->setFlag("/");
}
void MainWindow::on_equalButton_clicked()
{
int num = str.toInt();
model->setNum2(num);
QString s = QString:: number( model->calculate());
ui->label->setText(s);
str = "";
}
#ifndef MODEL_H
#define MODEL_H
#include<QString>
class Model
{
public:
Model();
void setNum1(int num);
void setNum2(int num);
void setFlag(QString f);
int calculate();
private:
int num1;
int num2;
QString flag;
};
#endif // MODEL_H
这是一段关于计算器的Qt程序,可以看到程序非常的长,要直接肉眼观察非常的困难。在程序运行过程中我们发现点击‘+’、‘-’、‘*’、‘/’符号键时程序异常退出,于是我们单独在这几段程序前设置断点
在调试的过程中,我们发现程序运行到model->setflag("=")时异常,于是通过检查model和setflag() 函数,我们发现错误的根源在于
这是一个典型的错误,指针类型的变量没有分配地址便进行调用操作,导致错误。
总结
可以看到,原本几百行的代码,通过程序调试,从整个程序到部分程序,从几段代码到一个数据一个函数,我们纠错的范围在缩小,而带来的收益便是Debug时间的缩短。
总之,练习程序调试是必须的技巧,同时如何快速调试,也是需要琢磨和思考的。
(虽然我觉得输出中间变量更方便)