プリプロセッサの文法 (マクロの文法)
## トークンの結合
#define HOGE(a) fo##a NSString *foo = @"Hello World"; NSLog(HOGE(o));
結果: Hello World
HOGE(o)のところがfooになるので、fooという変数をNSLogに与えたNSLog(foo);と書いたことと同じになり、
Hello Worldが出力される。
... 可変引数
__VA_ARGS__ で参照可能になる。
#define HOGE(...) NSLog(__VA_ARGS__) HOGE(@">>> %@ <<<", @"Hello World");
結果: >>> Hello World <<<
関数マクロ
すでに可変引数を説明してしまっているが、括弧を使う形で引数を受け取るマクロを定義できる。
#define MY_MAX(a, zzzz) (a) > (zzzz) ? a : zzzz NSLog(@"%d", MY_MAX(3,99));
結果: 99
fmt, ...
引数の名前は何でもよいのだが、フォーマット的な意味でfmtという引数の名前がよく使われているように思える。
#define MY_DEBUG(fmt, ...) NSLog(@"%d行目 " fmt, __LINE__, ##__VA_ARGS__) NSString *s = @"こんにちわ"; MY_DEBUG(@"s : %@", s);
結果: 22行目 こんにちわ
個人的には##いらないんじゃ?と思った
個人的には##__VA_ARGS__の##の部分要らない気がするのだけれど....違うのだろうか...
とおもったら
と思ったら答えが載っていました。
tez: Diary: VA_ARGS マクロ
__VA_ARGS__ が空のときのおまじないとか。
たしかに
MY_DEBUG(@"テスト");
としたとき
#define MY_DEBUG(fmt, ...) NSLog(@"%d行目 " fmt, __LINE__, __VA_ARGS__)
だとエラーになることを確認。
#defineした定数を#defineの右辺でも使いたいとき
普通に定数名を右辺に書けば展開されている
#define HELLO @"こんにちは" #define STR HELLO @"せかい" NSLog(@"%@", STR);
結果: こんにちはせかい