考虑以下代码,使用各种#define
语句;
#define PUSH 0x50
#define POP 0x58
#define NOP 0x90
#define JUNK __asm__(PUSH, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, POP)
#define J 0.752
#define L 27
前几个状态定义了一些HEX值,它们是汇编指令,然后是一组。
倒数第二行定义了一个名为J的浮点数。
final语句定义了一个名为L的整数。
这些内存定义是“无类型的”,因为它们是常量吗?我猜不是因为我无法想象它会如何起作用。编译器是否自动分配最大的relivant类型,例如float或int?
答案 0 :(得分:4)
这些不是“内存定义”。它们是预处理器宏。编译器本身没有它们的可见性,因为它们在运行之前都被替换(主要是通过复制和粘贴)。
答案 1 :(得分:2)
在调用编译器本地之前,您的宏将被字面序列替换(替换)它们所定义的字符序列。即你的宏甚至不是“十六进制值”。它们代表着没有语言级语义含义的字符序列。
替换后,编译器将正确看到这些字符序列,并根据周围的上下文进行相应的解释。在“典型”情况下,编译器将它们解释为整数常量。整数常量是C中的 rvalues ,它们没有与之关联的内存。从概念上讲,它们并不存在于记忆中。但这并不能使他们无类型。在C中,常量的格式定义了它的类型。 0.752
是double
类型的常量,而27
是int
类型的常量。
但同样,替代序列的语义含义可能(并且将会)取决于它所处的上下文。如果您愿意,可以将这些宏“实例化”为字符串文字,或者将它们与其他字符序列连接起来,从而完全改变它们的含义。
答案 2 :(得分:2)
具有#
前缀的所有这些语句(例如#define
,#include
和许多其他语句都不是编译器看到的真正的C / C ++语句。这些是所谓的预处理程序指令。
预处理器是一个软件,它在编译器处理之前遍历所有代码文件。预处理器在文件中搜索特殊命令 - 称为预处理程序指令。一旦找到指令,预处理器就会对代码文件执行一些操作。编译器只能编译原始代码文件上的预处理结果。
例如,当预处理器遇到#include
指令时,它只是将#include "whatever.h"
替换为文件whatever.h
的内容。只有在预处理器完成之后,编译器才能处理生成的文件 - 其中whatever.h
的内容已经替换为#include
。
#define
只是另一个预处理程序指令,用于将某些文本替换为另一段文本。
#define PUSH 0x50
告诉预处理器用PUSH
替换文件中找到的语句中的0x50
。 0x50
没有类型,它不是整数或常量或任何东西,只是粘贴到原始代码文件中的一段文本,在将文本PUSH
传递给编译器之前替换它。
编译器处理后,0x50
文本将根据其语法上下文进行编译。