C++ ⇒ VBA 書いて覚えるための初心者自己中記事

C++ ⇒ VBA 勉強の履歴を付けるというかノート代わりに使ってます

C++ マクロ 書いて覚えるための初心者自己中記事

マクロについて

マクロは #include に似ている

#include は別ファイルを差し込む

マクロはテキストを指定した場所に差し込む

 

差し込んでからコンパイル

#define FIVE_TIMES for(int i_ = 0 ; i_ < 5 ; ++i_) //これがマクロ
 
int main() {
 
	FIVE_TIMES { //ここでマクロ
		cout << "hello" << endl;
	}
	
	system("pause");
}

 必要なのは

#define  マクロ名 テキスト

 

ってか変数にアンダースコアつけるのなんなの?

 

テキストで初めて出てきたんだけど全く触れないし。

マクロ使わないで直接for 書いてアンダースコア使っても使えるし。

 

え。

 

もしかして意味ない???

 

 

次、マクロは引数をとれる

#define ANEY_TIMES(n) for(int i_ = 0 ; i_ < n ; ++i_) //型を書かない
 
int main() {
 
	ANEY_TIMES(7) { 
		cout << "hello" << endl;
	}
	
	system("pause");

 何回も書くのが面倒な処理をマクロで行うとはかどる

#define ARRAY_SIZE(n) (sizeof n / sizeof n[0])
 
int main() {
	int n[100];
	cout << ARRAY_SIZE(n) << endl;
	
	system("pause");
}

 

 関数型のマクロを複数行にわたって

まずは使ってない状態

const char* Open(ifstream& file, const char* filename) {
	file.open(filename);
	return file.is_open ? NULL : "ファイルを開けませんでした";
}
 
const char* GetLine(ifstream& file, string& line) {
	getline(file, line);
	return file.fail() ? NULL : "ファイルから読み込めませんでした";
}
 
 
 
int main() {
	const char* error = NULL;
 
	ifstream file;
	string line;
 
	error = Open(file, "test.txt");//この辺マクロにしたい
	if (error != NULL) {
		goto ON_ERROR;
	}
 
	error = GetLine(file, line);//この辺マクロにしたい
	if (error != NULL) {
		goto ON_ERROR;
	}
 
ON_ERROR:
	cerr << error << endl;
	return EXIT_FAILURE;
 
	
	system("pause");
}

 青地でアンダーライン引いてある部分だけが違うのでそこを引数にしてマクロにする

//関数実装部分は変化なし省略
 
//改行するときは \ を使う
#define ON_ERROR_GOTO(expr) \
error = (expr);\
if(error != NULL){ \
goto ON_ERROR; \
}
 
int main() {
	const char* error = NULL;
 
	ifstream file;
	string line;
 
	ON_ERROR_GOTO(Open(file, "test.txt")) //マクロですっきり
	ON_ERROR_GOTO(GetLine(file, line))    //マクロですっきり
 
ON_ERROR:
	cerr << error << endl;
	return EXIT_FAILURE;
 
	system("pause");
}

 

 

 マクロ注意点

マクロ名と引数の間に空白NG

マクロの差し込みテキスト内の引数はカッコで囲んでおいたほうが良い

 

 #define   マクロ定義

#undef   マクロ無効

 

 

 

 

 

assertマクロについて

デバッグ中だけチェックしたいチェック文があったら使う。

if 文の代わりにassert (  ); に条件式を書く。

false の場合はエラーの発生したファイル名と番号がわかる。

#include <cassert> で使える。

 

そしてこのassert を使った分はまとめて消すことが出来る。

方法は#include <cassert> より先に

#define NDEBUG

を定義すること。

 

それでなくなる。

assertマクロの文には副作用を持つ処理を書くと危険

副作用とは変数の代入や入出力処理。

これらの副作用を持つ処理があると

#define NDEBUG 

したときにその副作用の処理が消えて、予期せぬエラーが生まれる可能性があるため。

 ここまで