调试指南

调试指南

因为图床一些问题,本篇博客暂时不添加图片,能够自行运行代码片断查看运行结果。c++

1、预处理指令的妙用

参考文献:爽文219
一、使用ifdef注释
只有在宏定义了ifdef后判断的内容时,使用ifdef和endif括住的内容才会被编译运行。
样例:git

int main()
{
#define lky233
#ifdef lky233
	freopen("testdata.in", "r", stdin);
	freopen("testdata.out", "w", stdout);
#endif 
	int a, b;
	cin >> a >> b;
	cout << a + b << endl;
}

除了使用define进行宏定义,还能够在编译命令中添加 -D *** 实现。
例如:-D lky233
另外,ifndef表示若没有定义。
样例:github

int main()
{
#define lky233
#ifndef lky233
	freopen("testdata.in", "r", stdin);
	freopen("testdata.out", "w", stdout);
#endif 
	int a, b;
	cin >> a >> b;
	cout << a + b << endl;
}

还有就是,通常经常使用的OJ都有宏定义ONLINE_JUDGE。
(HOJ也有的)
二、define
define在调试中用来进行宏定义,并用来一句话注释全部调试代码函数

#define debug
#ifdef debug
printf("debug");
#endif

三、warning/pragma message()
使用warning/pragma message()在一些修改处进行警告,防止本身失智。学习

int main()
{
#warning
	int a,b;
#pragma message("debug")
	cout << a << b << endl;
}

2、cerr的使用

输出一些调试信息,但没有注释致使\({\color{red}{\mathrm {WA}}}\)?。
为了查看调试信息注释了freopen?
不要慌,快用\(cerr\)spa

cerr 一个ostream对象,关联到标准错误,一般写入到与标准输出相同的设备。默认状况下,写到cerr的数据是不缓冲的。Cerr一般用于输出错误信息与其余不属于正常逻辑的输出内容。 ——百度百科debug

简单来讲,cerr能够在你已打开文件输入输出的时候,依旧在屏幕上输出信息, 而非在文件中输入输出。
使用和cout是同样的。调试

int main()
{
	freopen("testdata.in", "r", stdin);
	freopen("testdata.out", "w", stdout);
	cerr << 1 << endl;
	cout << 2 << endl;
}

另一提,syzoj能够输出你的标准错误流。在OJ上debug
关于标准错误流, 还有一个clog,没用过,感兴趣的本身康康。code

3、assert

用于判断一些错误。
assert(),传入一个bool表达式,若是信息为假,程序会中止并抛出错误信息。对象

int main()
{
	assert(0);
}

4、使用dev进行debug

这个是dev的debug,要想学习gdb调试:请点我(虽然本质区别不大)
因为我的感受dev的debug太难用了,大多数状况我我的仍是喜欢手动调试。
使用时编译器先选择debug,以后进行编译。
因为一些缓冲区的问题,建议使用文件输入输出。
不然可能不可预测的翻车。
编译完成后摁下\(F5\)进行调试。
一、设置断点
调试状况下若没有断点程序将会直接正常运行,而且不会在控制台暂停。
单击行号以在该行设置断点。
程序会在这一行暂停运行。
二、添加查看
单击添加查看,输入变量名称,在左侧项目管理栏即可以看到所要查看的变量。
运行过程当中,右键能够修改变量值。
三、下一步/单步进入
单击[下一步]或使用\(F7\)进入下一步。将会执行下一个函数。
单击[单步进入]或使用\(F8\)进入该函数进行调试。

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 10;
int n;
int a[MAXN];
inline void out()
{
	for(register int i = 1; i <= n; ++i)
	{
		cout << a[i] << '\n';
	}
}
int main()
{
#ifdef lky233
	freopen("testdata.in", "r", stdin);
	freopen("testdata.out", "w", stdout);
#endif 
	scanf("%d", &n);
	for(register int i = 1; i <= n; ++i)
	{
		scanf("%d", &a[i]);
	}
	out();
	return 0;
}

四、RE报错
当调试一个RE的程序时,dev会暂停在RE的那行。若是是在函数中RE,会跳转到函数中。包括库函数,好比STL。
折腾半天想找一个RE的程序
我也不知道为何负下标没有RE。
可是,scanf不传地址就会RE啊。(初学C++常犯错误)

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 100;
int a[MAXN]; 
int n;
int main()
{
#ifdef lky233
	freopen("testdata.in", "r", stdin);
	freopen("testdata.out", "w", stdout);
#endif
	scanf("%d",n);
}

5、对拍

对拍是考场debug、证实正确性以及平时调试的利器。
贪心只能过样例
一、一个重要的maker

#include<bits/stdc++.h>
using namespace std;
int main()
{
	freopen("testdata.in", "w", stdout);
	srand(time(0)/* *new int */)
	int a = rand() % 10 + 1;
	int b = rand() % 10 + 1;
	cout << a << b << endl;
}

二、对拍程序

#include<bits/stdc++.h>
using namespace std;
int main()
{
	for(register int i = 1; i <= 10000; ++i)
	{
		system("maker.exe");
		system("force.exe");
		system("right.exe");
		//system("force.exe<testdata.in>force.out");
		//system("force.exe<testdata.in>right.out");
		if(system("fc force.out right.out"))
		{
			puts("wrong");
			exit(0);
		}
	}
}
相关文章
相关标签/搜索