Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
基于函数参数的C预处理器流控制_C_Arguments_C Preprocessor_Control Flow - Fatal编程技术网

基于函数参数的C预处理器流控制

基于函数参数的C预处理器流控制,c,arguments,c-preprocessor,control-flow,C,Arguments,C Preprocessor,Control Flow,我想做的是这样的事情 #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")) 将在输出上的三重循环内生成printf 及 将生成一些其他代码 这可能吗?您可以这样做: #define TRIPLE_LOO

我想做的是这样的事情

#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"))
将在输出上的三重循环内生成printf 及

将生成一些其他代码 这可能吗?

您可以这样做:

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

#define TRIPLE_LOOP()\
SOME_OTHER_CODE

我认为它会起作用:)

不,你不能这样做。“code”的值在运行时定义,而宏在编译时被替换。您必须使用不同的宏定义。

实际上您不能这样做,因为宏只能定义一次。您可以使用一些技巧来实现这一点:

#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

这几乎适用于我:)

#包括
#定义NARGS2(_1,N,…)N
#定义NARG(…)NARGS2(_VA_ARGS,1,0)
#定义三元组(…)\
做{\
如果(NARGS(_VA_ARGS){\
int i,j,k\

对于(i=0;i如果您的编译器是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\u LOOP\u 1
对应于空参数大小写,并且
TRIPLE\u LOOP\u
与其他情况相对应。
这里有一个测试。

为什么不呢?TRIPLE_CODE()不是TRIPLE_CODE()。你也可以定义一个(p1,p2,p3),#定义一个(p1,p2),#定义一个(p1)etcnope:(它给出了测试。c:5:1:警告:“乐趣”重新定义的测试。c:3:1:警告:这是上一个定义测试的位置。c:8:17:错误:宏“乐趣”已传递1个参数,但接受just@Hasturkun:这确实很可怕;
else
从未被执行过。然而,我正试图想出一个更可怕的解决方案,在
else
也可以工作的地方:)我使用了GNU CPP扩展,使用了
令牌粘贴操作符。
\define NARGS2(_1,_2,N,…)N
,和
#定义NARG(…)NARGS2(,######!!!!!!!!!!!!!!!!!。
#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();
}
#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__; }