2011-07-20 15 views
2
は出力にトリプルループ内のprintfが生成されますので、この

Cプリプロセッサのフロー制御は、関数の引数に応じて、

#define TRIPLE_LOOP(code)\ 
//if there is something in code \ 
for(...) for(...) for(...) { code }\ 
//if code is empty then\ 
SOME_OTHER_CODE 

その

TRIPLE_LOOP(printf("muhahaha")) 

ような何か私は何をしたいです

TRIPLE_LOOP() 

は、SOME_OTHER_CODEを生成します 彼の可能性?

答えて

-1

あなたはこれを行うことができます:

#define TRIPLE_LOOP(code)\ 
for(...) for(...) for(...) { code }\ 

#define TRIPLE_LOOP()\ 
SOME_OTHER_CODE 

を、私はそれがうまくいくと思います:)

+0

このように再定義できますか? – iammilind

+0

そして、どうしてですか? TRIPLE_CODE()はTRIPLE_CODE()ではありません。 #define A(p1、p2、p3)、#define A(p1、p2)、#define A(p1)など – Olympian

+0

これは動作しません。マクロを再定義することはできません – gtikok

1

んが、あなたがこれを行うことはできません。 "code"の値は実行時に定義され、マクロはコンパイル時に置き換えられます。異なるマクロ定義を使用する必要があります。

0

マクロは一度しか定義できないため、実際には実行できません。あなたはそれを達成するためにいくつかのトリックを使用することができます。

#define TRIPLE_LOOP(CONDITION, ...)\ 
if(CONDITION) {\ 
for(...) for(...) for(...) { __VA_ARGS__; }\ 
} \ 
else {\ 
SOME_OTHER_CODE \ 
} 

使用法:

TRIPLE_LOOP(true, printf("muhahaha")); // `true` can be 1 
TRIPLE_LOOP(false); // `false` can be 0 

しかし、引数を渡すことながら、あなたは常に正しいbool変数true/falseを渡すことを確認してください。

2

これはほとんど私の作品:)も

#include <stdio.h> 

#define NARGS2(_1, N, ...) N 
#define NARGS(...) NARGS2(__VA_ARGS__, 1, 0) 
#define TRIPLELOOP(...)       \ 
     do {          \ 
     if (NARGS(__VA_ARGS__)) {    \ 
      int i, j, k;       \ 
      for (i=0; i<2; i++) {     \ 
      for (j=0; j<2; j++) {    \ 
       for (k=0; k<2; k++) {    \ 
       __VA_ARGS__;     \ 
       }         \ 
      }         \ 
      }          \ 
     } else {        \ 
      printf("NO ARGS");     \ 
     }          \ 
     } while (0) 

int main(void) { 
    TRIPLELOOP(printf("haha"); puts("!")); 
    TRIPLELOOP(); 
} 

それはworks at ideone

+1

+1、それも恐ろしいです – Hasturkun

+0

@Hasturkun:恐ろしいことです。まだ 'else'も働いています。:) – pmg

+0

' ## 'トークンペースト演算子を使ったGNU CPP拡張を使って動作させました。 '#define NARGS2(_1、_2、N、...)N'、' #define NARGS(...)NARGS2(、## __ VA_ARGS__、1、0) 'を指定します。おそらく単純化することができます。 – Hasturkun

0

コンパイラがgccまたはMSVCの場合、次のコードが目的を達成することがあります。

#define EXPAND(x) x /* for MSVC */ 
#define CONCAT_(x, y) x ## y 
#define CONCAT(x, y) CONCAT_(x, y) 
#define CAR_(x, ...) x 
#define CAR(...) EXPAND(CAR_(__VA_ARGS__)) 
#define VA_ARGS_(...) , ##__VA_ARGS__ 
#define VA_ARGS(...) VA_ARGS_(__VA_ARGS__) 
#define IS_EMPTY(...) CAR(VA_ARGS(__VA_ARGS__) 1) 

#define TRIPLE_LOOP(...) \ 
    CONCAT(TRIPLE_LOOP_, IS_EMPTY(__VA_ARGS__))(__VA_ARGS__) 
#define TRIPLE_LOOP_1(...) SOME_OTHER_CODE 
#define TRIPLE_LOOP_(...) for(...) for(...) for(...) { __VA_ARGS__; } 

TRIPLE_LOOP_1は空の引数の場合に対応し、TRIPLE_LOOP_ は、他の場合に相当します。 ここにはideoneのテストがあります。

関連する問題