使用宏与其扩展之间的区别

时间:2010-09-24 08:48:59

标签: c

#define ADD(a,b) (a)+(b)

void foo1()
{
    int a=1, b=2;
    int k=0;
    while(k++ < 10000)
    {
        int c = ADD(a,b);
        a = c;
    }
}

void foo2()
{
    int a=1, b=2;
    int k=0;
    while(k++ < 10000)
    {
        int c = a + b;
        a = c;
    }
}

foo1和foo2之间有什么区别?有人问我这个问题,我找不到任何区别。两者似乎100%相同。关于堆栈上的内存分配可能有些不同?您可以尝试回答这个问题,假设记忆非常有限吗?

5 个答案:

答案 0 :(得分:5)

唯一的区别在于,不是像你一样编写宏,而是需要将整个宏包含在另外一组parens中:

#define ADD(a,b) ((a)+(b))

如果你没有做出那个修复,那么

ADD(3,4) * 5

等于23,但

(3 + 4) * 5

等于34。

将每个宏参数正确地包含在自己的parens中是很棒的,但是你还需要将整个宏包含在parens中以避免与优先级相关的错误。

答案 1 :(得分:4)

据我所知,这是完全一样的。

宏在预处理器中扩展,而不是编译。因此,最终结果与处理和内存成本完全相同。

唯一的区别是预处理可能需要更多时间。 (虽然可以忽略不计)

答案 2 :(得分:3)

就像他们说的那样,但有一点不同,ADD(5, 5) * 5将被假定为评估为50,而5 + 5 * 5将被假定为评估为30.实际上,正如您已经定义的那样,两者都是30,所以请务必在定义中添加额外的括号:#define ADD(a,b) ((a)+(b))

答案 3 :(得分:1)

没有区别,预编译器在代码编译之前运行,只是做了一个愚蠢的替换。

答案 4 :(得分:0)

就C编译器而言,只需要做很少的工作就可以了。

编译源文件的一个步骤是预处理。预处理的一个步骤是扩展宏。

手动扩展宏时,编译器不必这样做。