C 编译器如何处理枚举中的符号常量?

C 编译器如何处理枚举中的符号常量?,c,enums,macros,constants,enumeration,C,Enums,Macros,Constants,Enumeration,若我们谈论宏,编译器在预处理阶段处理宏,那个么枚举器呢。编译器如何看待它们。例如,请参见以下代码: #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, monday,

若我们谈论宏,编译器在预处理阶段处理宏,那个么枚举器呢。编译器如何看待它们。例如,请参见以下代码:

#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, monday, tuesday, 
            wednesday, thursday, friday, saturday); 
    return 0; 
} 

在这个特定的示例中,我甚至没有为枚举数据类型创建任何变量。我只是在printf语句中使用枚举常量。枚举数在内部的工作方式与宏类似吗?在预处理过程中,所有这些符号常量是否都将替换为整数常量?编译器究竟是如何处理它们的?

不,它们不像宏那样工作,而是像常量变量那样工作

因此,您的代码大致相当于:

#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; 
}

查看这里:

不,它们不像宏那样工作,它们更像常量变量

因此,您的代码大致相当于:

#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; 
}

请在此处查看:

否,枚举在内部的工作方式与宏不同,枚举是一种数据类型,在编译过程中进行计算,而预处理器将宏复制为文本

从gcc gnu文档中: 宏是给定名称的代码片段。无论何时使用该名称,它都会被宏的内容替换。宏有两种。它们的区别主要在于使用时的外观。类似对象的宏在使用时类似于数据对象,类似函数的宏类似于函数调用


枚举是C语言中用户定义的数据类型。它用于为整型常量指定名称,使程序易于阅读和维护。关键字“enum”用于声明枚举。

否,枚举在内部的工作方式与宏不同,枚举是一种数据类型,在编译过程中进行计算,而预处理器将宏复制为文本

从gcc gnu文档中: 宏是给定名称的代码片段。无论何时使用该名称,它都会被宏的内容替换。宏有两种。它们的区别主要在于使用时的外观。类似对象的宏在使用时类似于数据对象,类似函数的宏类似于函数调用

枚举是C语言中用户定义的数据类型。它用于为整型常量指定名称,使程序易于阅读和维护。关键字“enum”用于声明枚举

枚举数在内部的工作方式与宏类似吗

有些是,有些不是

所有这些都可以吗 期间,符号常量将替换为三个整数常量 预处理

不知道。除了预处理指令、定义的运算符和定义的宏名称之外,预处理器不知道一个标识符和另一个标识符。你可以试试这个:

#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
}
编译器是如何处理它们的

作用域内的枚举常量类似于其他整数常量,例如42,除了上面的警告,它们不会被预处理器解释为这样。例如,它们可以用在整数常量表达式中,用于各种用途,如switch语句中的case标签。该标准没有规定细节,但大多数编译器对它们的处理类似于宏,因为在可执行文件中没有为它们保留任何存储—源代码被视为在预处理后,枚举常量在表达式中出现的任何位置都被相应的整数值替换。当然,它们不能识别对象,因为它们不是&运算符的可接受操作数

这与常量限定变量的行为不同。它们识别实际对象,而不仅仅是常量。它们可能不会在常量表达式中使用,并且至少在抽象机器中有与它们相关联的存储,因此可以通过&运算符获取它们的地址

枚举数在内部的工作方式与宏类似吗

有些是,有些不是

所有这些都可以吗 期间,符号常量将替换为三个整数常量 预处理

不知道。除了预处理指令、定义的运算符和定义的宏名称之外,预处理器不知道一个标识符和另一个标识符。你可以试试这个:

#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
}
编译器是如何处理它们的

作用域内的枚举常量类似于其他整数常量,例如42,除了上面的警告,它们不会被预处理器解释为这样。例如,它们可以用在整数常量表达式中,用于各种用途,如switch语句中的case标签。该标准没有规定细节,但大多数编译器对它们的处理类似于宏,因为在可执行文件中没有为它们保留任何存储—源代码被视为在预处理后,枚举常量在表达式中出现的任何位置都被相应的整数值替换。当然,它们不能识别对象,因为它们不是 &接线员


这与常量限定变量的行为不同。它们识别实际对象,而不仅仅是常量。它们不能用在常量表达式中,至少在抽象机器中有与其相关的存储,因此,它们的地址可以通过&operator获得。

FYI:enum相关内容不会被预处理器以任何方式更改,除非您使用常规宏相关FYI:enum相关内容不会被预处理器以任何方式更改,除非您使用常规宏相关。。。除了在enum foo{sunday=1}中的主要例外;和const int周二=5;第一个是编译时常量,第二个不是。切换条{case sunday://*ok*/;case tunday://*nope-compiler error*/;}@pmg是的,当然,我大致改为非常roughly@Jabberwocky,问题不在于粗略地说,而在于调用const int constants类型的对象。。。。除了在enum foo{sunday=1}中的主要例外;和const int周二=5;第一个是编译时常量,第二个不是。切换条{case sunday://*ok*/;case tunday://*nope-compiler error*/;}@pmg是的,当然,我大致改为非常roughly@Jabberwocky,问题并不是太粗略,而是类型为const int constants的调用对象。您关注的是枚举类型,但问题是关于枚举常量的。这些宏和类对象宏之间确实有一些相似之处,也有一些不同之处。在这个答案中几乎没有提到这些。您主要关注枚举类型,但问题是关于枚举常量的。这些宏和类对象宏之间确实有一些相似之处,也有一些不同之处。这些基本上都没有在这个答案中提及。你的答案几乎澄清了所有问题,但只是一个基本的疑问仍然存在。我无法理解它是否以某种方式在内部被视为常量变量,而不是为什么它们没有与之关联的存储。也与此无关,但您能告诉我们为什么不能在开关情况下使用常量变量,但我们可以轻松地使用enum吗?@LocalHost,enum常量不被视为常量变量,正如这个答案已经说过的那样。常量限定变量与常量不同。您所询问的细节——是否存在关联存储,它们是否可用于形成常量表达式——是这种区别的直接后果之一。语言规范指出,常量(包括枚举常量)可能出现在常量表达式中,而对象标识符可能不会出现,尽管存在常量限定。您的答案几乎澄清了所有问题,但仍然存在一个基本疑问。我无法理解它是否以某种方式在内部被视为常量变量,而不是为什么它们没有与之关联的存储。也与此无关,但您能告诉我们为什么不能在开关情况下使用常量变量,但我们可以轻松地使用enum吗?@LocalHost,enum常量不被视为常量变量,正如这个答案已经说过的那样。常量限定变量与常量不同。您所询问的细节——是否存在关联存储,它们是否可用于形成常量表达式——是这种区别的直接后果之一。语言规范指出,常量(包括枚举常量)可能出现在常量表达式中,而对象标识符可能不会出现,尽管存在常量限定。