问题描述
如果我们谈论宏,则编译器会在预处理阶段处理宏,但枚举器呢?编译器如何看待它们。例如,请参见以下代码:
#include <stdio.h>
enum day {sunday = 1,monday,tuesday = 5,wednesday,thursday = 10,friday,saturday};
int main()
{
printf("%d %d %d %d %d %d %d",sunday,tuesday,thursday,saturday);
return 0;
}
在这个特定示例中,我什至没有为枚举数据类型创建任何变量。我只是在enumeration-constants
语句中使用printf()
。枚举器内部是否与宏类似?在预处理过程中,所有这些符号常量都将被整数常量替换吗?编译器如何精确地处理它们?
解决方法
不,它们不像宏那样工作,而是以某种方式像const变量那样工作。
因此您的代码与此大致相当:
#include <stdio.h>
const int sunday = 1,monday = 2,tuesday = 5,wednesday = 6,thursday = 10,friday = 11,saturday = 12;
int main()
{
printf("%d %d %d %d %d %d %d",sunday,monday,tuesday,wednesday,thursday,friday,saturday);
return 0;
}
在此处查看:https://www.godbolt.org/z/cErv5W
,枚举器在内部是否与宏类似?
是的,有些不。
所有这些 在此期间,符号常量将替换为整数常量 预处理?
不。除预处理指令,defined
运算符和已定义的宏名称之外,预处理器不知道另一个标识符。您可以尝试以下方法:
#include <stdio.h>
#define MACRO_TRUE 1
enum bool_enum { ENUM_FALSE = 0,ENUM_TRUE = 1 };
int main(void) {
#if MACRO_TRUE
puts("Macro identifiers are known to the preprocessor.");
#else
puts("Macro identifiers are not known to the preprocessor.");
#endif
#if ENUM_TRUE
puts("Enum constants are known to the preprocessor.");
#else
puts("Enum constants are not known to the preprocessor.");
#endif
}
输出应为
Macro identifiers are known to the preprocessor.
Enum constants are not known to the preprocessor.
编译器如何精确地处理它们?
作用域内的枚举常量类似于其他整数常量,例如42
,但上述警告除外,即预处理器不会解释它们。例如,它们可以用在整数常量表达式中,这对于各种目的都是必需的,例如case
语句中的switch
标签。该标准未指定细节,但是大多数编译器将它们与宏类似地对待,因为在可执行文件中没有为它们保留任何存储空间-将源视为将枚举常量替换为其相应的整数值,无论它们出现在表达式中的何处,预处理后。当然,它们不能识别对象,因为它们不是&
运算符的可接受的操作数。
这与const
限定变量的行为有所区别。这些标识实际对象,而不仅仅是常量。它们可能不会在常量表达式中使用,并且它们确实具有与它们关联的存储(至少在抽象机中),因此可以通过&
运算符获取它们的地址。
不,枚举在内部不像宏那样工作,枚举是一种数据类型,在编译时会被求值,而预处理器会将宏复制为文本。
从gcc gnu文档中: 宏是已命名的代码片段。每当使用该名称时,它就会被宏的内容替换。有两种宏。它们的主要区别在于使用时的外观。类对象宏在使用时类似于数据对象,类函数宏类似于函数调用。
枚举是C语言的用户定义数据类型。它用于为整数常量分配名称,从而使程序易于阅读和维护。关键字“ enum”用于声明枚举。