C/C++のマクロの使い方(マクロネスト/マクロ展開/可変パラメータマクロ)


まず、C++を使用する場合は、マクロの使用をできるだけ避ける必要があります.
そして、マクロには強さと便利さがあります.次に、簡単に紹介します.仕事の勉強の中で、出会ったマクロの使い方について、仕事のまとめです.
1、#および##
#:マクロパラメータを文字列に変換します.このパラメータマクロが何であれ、「原形」は文字列で表示されます.
#define Log(x)printf("%s",#x)
(1)、Log(10);//出力10は、printfの中に「%d」ではなく「%s」があることに注意する.
(2)、int nCount=10;
       Log(nCount); //出力はnCountで、10ではありません
##接続子(concatenation)と呼ばれ、マクロパラメータを前のtoken(パラメータ/文字列スペースなど)に接続します.
のように
#define PARAM_INVILED (-1)
#define PARAM_INVILED_STR「パラメータエラー」
#define ShowErrInfo(ERRNO) printf("[Code:%d]:%s",ERRNO,ERRNO##_STR);
出力:[Code:-1]:パラメータエラー
2、マクロネストマクロ
'#'または'###'がある場合、マクロネストマクロは有効に展開されず、マクロを追加して変換する必要があります.
次のようになります.
#define INT_X 1
#define INT_Y 2
#define INT_SPLICE(x,y) (x##y)
printf("%d",INT_SPLICE(1,2));//大丈夫、出力12;
printf("%d",INT_SPLICE(INT_X,INT_Y));//コンパイルエラー;
この場合、マクロ定義には次の処理が必要です.
#define _INT_SPLICE(x,y) (x##y)
#define INT_SPLICE(x,y) _INT_SPLICE(x,y)
するとprintf("%d",INT_SPLICE(INT_X,INT_Y);//出力12;
2、可変パラメータマクロ
CマクロではVariadic Macro,すなわち変参マクロと呼ぶ.例:#define Log(fmt,...)printf(fmt,##__VA_ARGS__)
 #define Log(fmt,args...) printf(fmt,args)
最初にデフォルトのマクロ__を使用VA_ARGS__,##この接続記号が果たす役割は_VAR_ARGS__空の場合は、前のカンマを消します.
第2のマクロでは、変参をargsと明示的に命名する、マクロ定義ではargsで変参を指すことができる.
可変パラメータマクロは、printfのいくつかのテクニックを発見しました.以前は発見されていませんでしたが、プロジェクトのログシステムを一時的に代替し、画面に出力してデバッグに使用することができます.
#ifdef WIN32
#define TrimFilePath(x) strrchr(x,'\\')?strrchr(x,'\\')+1:x
#else //*nix
#define TrimFilePath(x) strrchr(x,'/')?strrchr(x,'/')+1:x
#endif

#define LogDebug(fmt, ...)   \
printf("[DEBUG] [%s(%d)] : " fmt"
",TrimFilePath(__FILE__),__LINE__,##__VA_ARGS__) #define LogInfo(fmt, ...) \ printf("[INFO ] [%s(%d)] : " fmt"
",TrimFilePath(__FILE__),__LINE__,##__VA_ARGS__) #define LogWarn(fmt, ...) \ printf("[WARN ] [%s(%d)] : " fmt"
",TrimFilePath(__FILE__),__LINE__,##__VA_ARGS__) #define LogError(fmt, ...) \ printf("[ERROR] [%s(%d)] : " fmt"
",TrimFilePath(__FILE__),__LINE__,##__VA_ARGS__)

ZhaiPillary
2016-12-17