我试图理解像Macros这样的功能的想法,但是有一点让我迷惑。例如,我们说:
#define Max(a,b) ((a)>(b)) ? (a):(b))
我称之为
int i = Max(4,5);
这将评估相当于a>b
的条件表达式?如果是,则a,否则b。但我对Max函数如何知道如何处理参数感到困惑。与实际函数不同,实现不是在调用程序的代码中编写的。是定义语句右边的声明为我做这个吗?这对我来说只是一个新事物,我想确保我理解这里发生的事情。
宏的功能的这个特殊部分让我很困惑。我知道这些类型的宏对于降低开销成本很有用,因为它们排除了在堆栈上节省内存的JSR RTS处理器指令。
答案 0 :(得分:11)
#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;
}
答案 1 :(得分:5)
在预处理之后,编译器实际看到的是:
int i = ((4)>(5)) ? (4):(5));
传递给宏的参数将替换为宏的主体。
答案 2 :(得分:4)
停止考虑像可编译代码一样的宏。宏由预处理器“解析”,而不是在编译阶段。因此,通过宏定义,您只需定义如何处理文本文件中的某些字符串。只有预处理器的输出传递给编译器。您可以使用gcc -E
在预处理器后查看来源。它仍然是这个阶段的C代码,但没有任何预处理器指令。
希望这会对你有所帮助。
答案 3 :(得分:3)
尝试使用gcc -E
构建代码,并在编译代码之前查看代码的外观
事实上,在构建过程中,编译器会将您的实际代码转换为预处理器代码。 在预处理器阶段,编译器用其内容替换c代码中的所有宏,并生成另一个称为预处理器代码的代码,然后编译器从预处理器代码生成目标代码
gcc -E
允许您查看预处理器代码