我正在尝试理解typedef和define之间的区别。在SO上的这个问题中有很多好的帖子,但我不理解其中一个帖子所说的:
#define是一个预处理器标记:编译器本身不会看到它。
typedef是一个编译器标记:预处理器不关心它。
请问有人能够详细解释一下吗?我对这里的预处理器一词感到困惑。
#define是一个预处理器标记:编译器本身不会看到它。
typedef是一个编译器标记:预处理器不关心它。
请问有人能够详细解释一下吗?我对这里的预处理器一词感到困惑。
预处理器是在编译器之前运行的程序,主要执行文本替换。当你写:
#define X 10
int main()
{
int x = X;
}
int main()
{
int x = 10;
}
然后编译器使用预处理的输出进行其操作。
typedef
是编译器能够理解的结构。当你编写:
typedef unsigned int uint_32;
uint32
实际上是unsigned int
的别名。这个别名由编译器本身处理,涉及比简单文本替换更多的逻辑。这在一个简单的例子中变得明显:typedef int my_int;
int main()
{
unsigned my_int x; // oops, error
}
typedef
是像预处理器一样的简单文本替换机制,那么它就可以工作,但是这是不允许的,编译会失败。预处理器是在任何编译开始之前发生的阶段。它读取特定的宏和符号进行替换。通常只有一到两个步骤,扫描整个源文件并生成一个符号表来替换或扩展宏。
当所有替换完成后,语法分析器接管对源文件进行词法分析和语法分析,生成抽象语法树,生成代码,链接库并生成可执行文件/二进制文件。
在C/C++/ObjC中,预处理指令以'#'开头,后跟指令名称,例如"define"、"ifdef"、"ifndef"、"elif"、"if"、"endif"等。
预处理之前:
#define TEXT_MACRO(x) L##x
#define RETURN return(0)
int main(int argc, char *argv[])
{
static wchar_t buffer[] = TEXT_MACRO("HELLO WORLD");
RETURN ;
}
预处理完成后:
int main(int argc, char *argv[])
{
static wchar_t buffer[] = L"HELLO WORLD";
return (0);
}
#line
指令”的问题:这是C语言实现的一些内部行为。如果任何预处理器(独立的或内置于编译器中的)留下#line
指令,那么按照C标准规定的预处理工作还没有完成,编译器(至少在概念上)仍然需要通过删除它们来完成预处理。在C标准指定的翻译模型中,#line
指令不能留下,因为它们无法被词法语法解析。 - undefined #define WORD "newword"
int main()
{
printf("this is word: %s\n", WORD);
return 0;
}
cpp运行后会变成什么
int main()
{
printf("this is word: %s\n", "newword");
return 0;
}
typedef被用来表示“如果我说到Type
,就意味着我指的是struct more_complex_type
”。它在编译时使用,并且在cpp
处理前后保持不变。
预处理器是在编译器编译代码之前执行的“引擎”。#define #include
是预处理指令或宏,因此预处理器引擎执行与指令相关的代码。当预处理器完成后,编译器看不到指令/宏。但是像 typedef
, if
, while
等结构是由编译器理解的。
这意味着预处理器在编译器之前运行,并在将源代码传递给编译器之前修改源代码。因此,编译器永远看不到某些代码。例如:
#define ONE 1
int x = ONE;
当您编译此代码时,预处理器会将其转换为以下内容:
int x = 1;
然后将新文本传递给编译器。因此,编译器看不到文本ONE
。