C++ 预处理在编译器中到底意味着什么
我试图理解typedef和define之间的区别。有很多好的帖子,特别是在,但是我不能理解的职位,国家C++ 预处理在编译器中到底意味着什么,c++,C++,我试图理解typedef和define之间的区别。有很多好的帖子,特别是在,但是我不能理解的职位,国家 #define是一个预处理器令牌:编译器本身永远不会看到它。 typedef是一个编译器标记:预处理器不关心它 有人能再详细解释一下吗。我对这里的术语“预处理器”感到困惑。预处理器是在任何编译开始之前发生的一个阶段。它读取要替换的特定宏和符号。通常是一到两次。它扫描整个源文件,并生成一个符号表来替换或扩展宏 完成所有替换后,语法分析器将接管对源文件进行词法分析、生成抽象语法树、生成代码、链接库
#define
是一个预处理器令牌:编译器本身永远不会看到它。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);
}
预处理后:
#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);
}
如果我没记错的话,Kernighan和Ritchie的《C编程语言》第二版有一个例子,他们展示了如何创建自己的预处理器及其工作原理。此外,Plan9C编译器将这两个过程(编译和预处理)分开。允许您在其中使用自己的预处理器
退房并离开。通过查看这些程序的输入和输出,您可以更深入地了解预处理器实际上是什么
另一个小秘密:如果你有一个预处理器,你可以用拉丁语/德语/西班牙语来编写C:)当涉及到编译时,你的源代码要经过很多步骤。在这些步骤中,有预处理 预处理器是在编译器之前运行的程序,它执行所有
启动的指令,如\include
、\define
等
在您的特定情况下,#define WORD newword
是一个指令,它在编译程序之前会说:“用newword替换所有出现的单词”
如果您想查看它的运行情况,请尝试运行cpp file.c
并检查输出以了解它的功能
文件.c
#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\u complex\u Type
”,它在编译时使用,在cpp
过程前后保持不变。预处理器是编译器编译代码之前执行的“引擎”。
#define#include
是预处理器指令或宏,因此预处理器引擎执行与指令相关的代码。当预处理器完成时,编译器看不到任何指令/宏。
但是,诸如
typedef
、if
、while
等构造。。编译器可以理解。预处理器是在编译器之前运行的程序,基本上执行文本替换。当你写作时:
#define X 10
int main()
{
int x = X;
}
typedef unsigned int uint_32;
预处理器将该文件作为输入,进行处理,并输出:
int main()
{
int x = 10;
}
然后编译器处理预处理的输出
另一方面,typedef
是编译器理解的构造。当你写作时:
#define X 10
int main()
{
int x = X;
}
typedef unsigned int uint_32;
编译器知道,uint32
实际上是unsigned int
的别名。这个别名由编译器自己处理,比简单的文本替换涉及更多的逻辑。通过一个简单的例子,这一点变得显而易见:
typedef int my_int;
int main()
{
unsigned my_int x; // oops, error
}
如果<代码> TyPulf是一个简单的文本替换机制(如预处理器是这样),那么它就可以工作,但是它是不允许的,并且不能编译。
< P> C和C++预处理器是编译过程中很早就发生的逻辑阶段。预处理器通过有条件地删除部分文件(#if
、#elif
、#elif
、#else
、#else
、#endif
、以及变体#ifdef
)来将源文件转换为翻译单元,通过宏替换。宏是通过#define
定义的;宏可以由扫描源的预处理器检测
预处理器消除了大多数以#
开头的行(它只留下#line
指令和它自己在#line
上的缩写变体,以告诉编译器源代码来自何处)。然后,编译器本身会看到预处理的结果,并编译定义的源代码
预处理器通常不会修改单词typedef
。一个疯狂的程序员可以为typedef
定义一个宏,而预处理器可能并不在意;当定义的宏与语言中的任何关键字同名时,程序员不能合法地包含任何系统头。但是,否则,typedef
是编译器的问题,而不是预处理器的问题。sizeof()
也是如此;预处理器并不理解这一点
通常有编译器选项允许您查看预处理的输出。对于
gcc
,选项是-E
和-P,这意味着预处理器在编译器之前运行,并在将源代码传递给编译器之前修改源代码。因此,编译器永远不会看到某些代码。例如:
#define ONE 1
int x = ONE;
编译时,预处理器将其更改为:
int x = 1;
并将新文本传递给编译器。因此,编译器看不到文本ONE
+1正确答案,而您先给出了答案。不过,举个例子就好了