代码之家  ›  专栏  ›  技术社区  ›  Dominic Bou-Samra

定义是否等同于函数?

c
  •  1
  • Dominic Bou-Samra  · 技术社区  · 15 年前

    #define IX(i,j) ((i)+(N+2)*(j))
    

    相当于:

    int IX(int i, int j) {
    
        return ((i)+(N+2)*(j));
    
    }
    

    5 回复  |  直到 14 年前
        1
  •  6
  •   Joel Rein    15 年前

    编译器永远看不到宏-预处理器替换文本。

    所以,当你写的时候:

    result = IX(5, 3);

    result = ((5)+(N+2)*(3));

    这可能会对行为产生影响,但这取决于您的宏。在这种情况下,没有那么多(也有性能和调试方面的差异,但我们在这里不必担心它们)。

    例如,您这样定义宏(注意 变量)

    #define IX(i,j) ((i)+(i+2)*(j))

    并这样称呼:

    result = IX(++i, j);

        2
  •  3
  •   dublev    15 年前

    #defines 是预处理器命令。当代码被编译时,IX(i,j)在任何地方都被它的定义替换。可以将其视为复制粘贴操作。因为这是在编译代码时发生的,所以IX(i,j)不返回类型。这种类型安全性的缺乏既是一个特点,也是一个缺点,请谨慎使用。

        3
  •  3
  •   wallyk    15 年前

    #define 是宏,一种源代码字符串替换功能。

    你的例子 IX() 函数有许多与执行代码相关的属性,比如指令只编译一次、有地址和需要整数参数。

    宏接受参数,但在尝试算术之前,它没有类型处理。即使这样,预处理器可以计算的任何参数都可以做一些有用的事情。或者它可以做一些意想不到的事情。

    作为一个简便的经验法则,使用的宏越多,代码的可理解性和可维护性就越差。

        4
  •  2
  •   Michael Madsen    15 年前

    在这种特殊情况下

    宏实际上只是在实际编译代码之前执行的文本替换,因此不需要类型信息;宏的使用只是被宏内容替换,其余的由编译器处理。

    IX(i++,j--) 根据它是函数还是宏的不同执行:如果是宏,参数在引用时进行求值;如果是函数,参数在调用函数时进行求值。

    由于没有参数被引用两次,所以在执行每一个参数之后没有明显的差异,但是它们仍然被区别对待。

        5
  •  0
  •   David E.    15 年前

    所有的答案都是正确的。

    由于宏是在编译器将代码翻译成机器指令之前由预处理器处理的,因此它们可能会产生其他人提到的有趣的副作用。

    我不完全同意宏降低代码可理解性的说法。我认为,如果谨慎、明智地使用它们,并且可以证明它们是正确的,那么它们可以导致更容易理解(我敢说吗?)自我记录代码。

    例子:

    #define MAX(N1,N2) ((N1) > (N2) ? (N1) : N2))
    biggest = MAX(temperatureOne, temperatureTwo);
    

    是的,我知道MAX(x++,y)会有不良的副作用,但这就是智能使用的原因。