C++ 预处理在编译器中到底意味着什么

C++ 预处理在编译器中到底意味着什么,c++,C++,我试图理解typedef和define之间的区别。有很多好的帖子,特别是在,但是我不能理解的职位,国家 #define是一个预处理器令牌:编译器本身永远不会看到它。 typedef是一个编译器标记:预处理器不关心它 有人能再详细解释一下吗。我对这里的术语“预处理器”感到困惑。预处理器是在任何编译开始之前发生的一个阶段。它读取要替换的特定宏和符号。通常是一到两次。它扫描整个源文件,并生成一个符号表来替换或扩展宏 完成所有替换后,语法分析器将接管对源文件进行词法分析、生成抽象语法树、生成代码、链接库

我试图理解typedef和define之间的区别。有很多好的帖子,特别是在,但是我不能理解的职位,国家

#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正确答案,而您先给出了答案。不过,举个例子就好了