調試指南

調試指南

因爲圖牀一些問題,本篇博客暫時不添加圖片,能夠自行運行代碼片斷查看運行結果。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);
		}
	}
}
相關文章
相關標籤/搜索