6

我试图理解像宏这样的函数的概念,但是有几点让我感到困惑。例如说我们有:

#define Max(a,b)  ((a)>(b)) ? (a):(b))

我这样称呼它

int i = Max(4,5);

这将评估一个相当于a>b?的条件表达式 如果是则a,否则为b。但我对 Max 函数如何知道如何处理参数感到困惑。与实际函数不同,实现不是用调用程序中的代码编写的。定义语句右侧的语句是否为我执行此操作?这对我来说只是一件新事物,我想确保我了解这里发生的事情。

像宏这样的特殊功能部分让我感到困惑。我知道这些类型的宏对于降低开销成本很有用,因为它们排除了 JSR RTS 处理器指令,从而节省了堆栈上的内存。

4

4 回答 4

13
#define Max(a,b)  ((a)>(b)) ? (a):(b))

是一个宏,除了在您的代码中进行简单的文本替换之外什么都不会导致,这意味着在预处理此行期间:

int i = Max(4,5);

改为:

int i = ((4)>(5)) ? (4):(5));

请注意,在使用像这样的宏时没有类型安全性,并且在调试代码时也会非常困难。好的经验法则是:当您可以使用函数实现相同功能时,不要使用宏

int max(int a, int b) {
    return (a > b) ? a : b;
}
于 2013-03-22T16:45:49.207 回答
5

编译器在预处理之后实际看到的是:

int i = ((4)>(5)) ? (4):(5));

传递给宏的参数被替换到宏的主体中。

于 2013-03-22T16:38:24.873 回答
5

停止思考宏之类的可编译代码。宏由预处理器“解析”,而不是实际上在编译阶段。因此,通过宏定义,您只需定义如何处理文本文件中的某些字符串。只有预处理器的输出被传递给编译器。您可以使用gcc -E在预处理器之后查看您的源代码。在这个阶段它仍然是 C 代码,但没有任何预处理器指令。

希望这会帮助你。

于 2013-03-22T16:56:01.927 回答
3

尝试使用 构建您的代码,gcc -E并在编译之前查看您的代码的外观

事实上,在构建过程中,编译器会将您的实际代码转换为预处理器代码。在预处理器阶段,编译器将 c 代码中的所有宏替换为其内容并生成另一个称为预处理器代码的代码,然后编译器从预处理器代码生成目标代码

gcc -E允许您查看您的预处理器代码

于 2013-03-22T16:38:17.503 回答