1

考虑以下带有各种#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 的浮点数。

最后一条语句定义了一个名为 L 的整数。

这些内存定义是否“无类型”,因为它们是常量?我猜不是因为我无法想象那会如何工作。编译器是否会自动分配最相关的类型,例如 float 或 int?

4

3 回答 3

4

这些不是“内存定义”。它们是预处理器宏。编译器本身看不到它们,因为它们在运行之前都被替换(基本上是通过复制和粘贴)。

于 2013-09-29T18:54:16.123 回答
2

在调用编译器之前,您的宏将被它们定义为代表的字符序列逐字替换(替换)。即你的宏甚至不是“十六进制值”。它们代表没有附加语言级别语义含义的字符序列。

在替换之后,这些字符序列将被编译器正确地看到,并将根据周围的上下文进行相应的解释。在“典型”情况下,它们被编译器正确解释为整数常量。整数常量是C 中的右值,它们没有与之关联的内存。从概念上讲,它们不存在于内存中。但这并没有使它们成为无类型的。在 C 中,常量的格式定义了它的类型。0.752是一个类型的常数double27而是一个类型的常数int

但是同样,替换序列的语义可能(并且将)取决于它所在的上下文。如果您愿意,您可以将这些宏“实例化”为字符串文字,或者将它们与其他字符序列连接,从而完全改变它们的含义。

于 2013-09-29T18:59:31.240 回答
2

所有这些带有#前缀的语句,例如#define#include以及许多其他语句都不是编译器看到的真正的 C/C++ 语句。这些就是所谓的预处理器指令。

预处理器是一个软件,它在编译器开始处理之前遍历所有代码文件。预处理器在文件中搜索特殊命令 - 称为预处理器指令。一旦找到指令,预处理器就会对代码文件执行一些操作。编译器只能编译原始代码文件的预处理结果。

例如,当预处理器遇到#include指令时,它只是简单地将 替换#include "whatever.h"为文件的内容whatever.h。只有在预处理器完成后,编译器才开始处理生成的文件——其中的内容whatever.h已经替换了#include.

#define只是另一个预处理器指令,用于将某些文本替换为另一段文本。

#define PUSH 0x50

告诉预处理器将PUSH在文件中找到的语句中的 a替换为0x50. 没有类型,0x50它不是整数或常量或任何东西,只是粘贴到原始代码文件中的一段文本,PUSH在传递给编译器之前替换文本。

一旦被编译器处理,0x50文本将根据其语法上下文进行编译。

于 2013-09-29T19:27:21.683 回答