C语言中类似函数的宏定义

ric*_*ard 7 c gcc c-preprocessor

我想定义一个像MACRO这样的函数.即

#define foo(x)\
#if x>32\
 x\
#else\
 (2*x)\
#endif
Run Code Online (Sandbox Code Playgroud)

那是,

if x>32, then foo(x) present x
else, foo(x) present (2*x)
Run Code Online (Sandbox Code Playgroud)

但我的海湾合作委员会抱怨:

int a = foo(31);
Run Code Online (Sandbox Code Playgroud)

我认为C预处理器应该正确处理.因为在编译时,它知道x=33.它可以代替foo(33)(2*33)

Joh*_*itb 13

你可以如下

#define foo(x) ((x) > 32 ? (x) : (2 * (x)))
Run Code Online (Sandbox Code Playgroud)

但是这次评估x多次.您可以改为创建一个更干净的静态函数

static int foo(int x) {
  if(x > 32) 
    return x;
  return 2 * x;
}
Run Code Online (Sandbox Code Playgroud)

然后你也可以传递foo有副作用的东西,副作用只发生一次.

什么你写使用的#if,#else#endif预处理指令,但你需要,如果你传递变量的宏观和要评估他们的价值使用的语言结构.在实际语言结构中使用ifelse语句也不起作用,因为控制流语句不会计算为值.换句话说,if语句只是转向控制流("如果A,则执行B,否则执行C"),而不是评估任何值.

  • @richard:使函数内联 - 如果在编译时知道该值,编译器通常会在编译时执行求值.即使对于未标记为"内联"的静态函数,编译器也可以这样做.您甚至可以通过更现代的编译器/链接器工具获得"extern"函数优化的好处(但可能性会降低).使用VS2008进行的快速测试表明,即使在单独的源文件中定义了`extern`,它也没有问题内联litb的`foo()`函数.传递文字整数时,结果在编译时计算. (3认同)
  • @richard :(继续) - 使用今天的工具,几乎不需要担心你的问题涉及的"优化"类型.通常,您不需要使用这些类型的宏/预处理器技巧来跳过"运行时节省时间".首先以正确,可维护和使用有效算法的方式编写代码(注意:这与尝试计算周期不同).当事实证明最初的尝试不够快时,只担心跳过篮球. (3认同)

Van*_*aro 8

#define \
    foo(x) \
    ({ \
        int xx = (x); \
        int result = (xx > 32) ? xx : (2*xx); \
        result; \
    })
Run Code Online (Sandbox Code Playgroud)

  • @Vanni:我忘记了GCC有一个名为'Statement Expressions'的扩展名.由于提出问题的人用"gcc"标记了它,这对他来说可能没问题.但是,我认为一个简单的内联函数也可以工作,并且更加便携. (3认同)
  • @Michael:感谢您指出这是gcc扩展!我不知道它的名字,而且它不便于携带!:) (2认同)

小智 3

考虑:

int x = rand()
int y = foo( x );
Run Code Online (Sandbox Code Playgroud)

x 在编译时是未知的。