如果我将宏定义为#define LOGIC_ONE 1
并想在案例陈述中使用LOGIC_ONE
,那么LOGIC_ONE
会考虑哪种类型?
它是否被识别为int
,因为我为值1定义了它?
答案 0 :(得分:19)
C ++宏是简单的文本替换。
在编译器启动时,预编译器已将LOGIC_ONE
替换为1
。它就像你现在就写1
一样。 (在这种情况下,这是一个int literal ...)
编辑以在评论中包含讨论:
如果您(或有权访问您代码的其他人)将您的#define LOGIC_ONE 1
更改为#define LOGIC_ONE "1"
,则会改变其在您的计划中的行为并成为const char[]
字面值。
修改强>
由于这篇文章比我预期的更受关注,我想我会为那些好奇的人添加对C++ 14 Standard的引用:
2.2翻译阶段 [lex.phases]
(...)
4.执行预处理指令,扩展宏调用,以及 _Pragma一元运算符表达式被执行。 (...)然后删除所有预处理指令 (...)
7.分隔标记的空白字符不再重要。每个预处理令牌都转换为令牌。 (2.6)。由此产生的标记在语法和语义上进行分析并翻译为翻译单元。
如上所述,宏在阶段4中被替换,之后不再存在。 “语法和语义”分析发生在第7阶段,代码被编译(“翻译”)。
整数文字在
中指定2.13.2整数文字 [lex.icon]
(...)
整数文字是一个没有句点或指数部分的数字序列,可选地分隔单引号,在确定其值时将被忽略。整数文字可以具有指定其基数的前缀和指定其类型的后缀 (...)表5 - 整数文字的类型
Suffix | Decimal literal | Binary, octal, or hexadecimal literal ----------------------------------------------------------------------------- none | int | int | long int | unsigned int | long long int | long int | | unsigned long int | | long long int | | unsigned long long int ----------------------------------------------------------------------------- u or U | unsigned int | unsigned int | unsigned long int | unsigned long int | unsigned long long int | unsigned long long int ----------------------------------------------------------------------------- l or L | long int | long int | long long int | unsigned long int | | long long int | | unsigned long long int ----------------------------------------------------------------------------- Both u or U | unsigned long int | unsigned long int and l or L | unsigned long long int | unsigned long long int ----------------------------------------------------------------------------- ll or LL | long long int | long long int | unsigned long long int ----------------------------------------------------------------------------- Both u or U |unsigned long long int | unsigned long long int and ll or LL | |
字符串文字在
中指定2.13.5字符串文字 [lex.string]
(...)
1字符串文字是由双引号括起来的字符序列(如2.13.3中所定义),可选地以R,u8,u8R,u,uR,U,UR,L,rLR为前缀,如“...... “,R”(...)“,u8”......“,u8R”**(...)**“,u”......“,uR”*〜(...)*〜“ ,U“......”,UR“zzz(...)zzz”,L“......”或LR“(...)”。 (...)
6在转换阶段6之后,不以encoding-prefix开头的字符串文字是普通的字符串文字,并使用给定的字符进行初始化。
7以u8开头的字符串文字,例如u8“asdf”,是UTF-8字符串文字。
8普通字符串文字和UTF-8字符串文字也称为窄字符串文字。窄字符串文字的类型为“nconst char
”数组,其中n是下面定义的字符串的大小,并且 静态存储时间(3.7)。
答案 1 :(得分:11)
预处理器定义没有类型 - 它们基本上只是粘贴"在它们出现的代码中。例如,您在声明中使用它;
int foo = LOGIC_ONE;
然后它将被解释为整数。 (编译器在预处理器之后运行,只将代码视为int foo = 1;
)您甚至可以在诸如;
int foo##LOGIC_ONE;
然后您将创建变量foo1
。育!
采用宏定义的另一个例子;
#define LOGIC_ONE hello
int LOGIC_ONE = 5;
printf("%d\n", hello);
这完全有效,并声明一个名为hello的int,但表明没有"类型"对于定义 - hello
仅在代码中遇到LOGIC_ONE
时被替换。
除非绝对必要,否则请避免使用预处理器宏。专业编码标准通常禁止或严格限制预处理器的使用。通常总是有比使用宏更好的方法。例如,考虑这些替代方案;
static const int LOGIC_ONE = 1;
enum { LOGIC_ONE = 1 };
预处理器是学习者在C中陷入困境的快捷方式。
答案 2 :(得分:8)
LOGIC_ONE在出现的任何地方都被替换为1。就编译器而言,LOGIC_ONE不存在,它只看到1.所以你的问题是'是1是一个int?'。答案是 - >这取决于你输入1
的位置答案 3 :(得分:6)
宏是文本替换。 1
的类型为constexpr int
。