顾名思义,预处理器是在编译之前处理源代码的程序。在C/C++中编写程序和执行程序之间有许多步骤。在我们真正开始学习预处理器之前,让我们先看看这些步骤。
您可以在上图中看到中间步骤。程序员编写的源代码存储在文件程序中。c、 然后,该文件由预处理器处理,并生成一个名为program的扩展源代码文件。这个扩展文件由编译器编译,并生成一个名为program的目标代码文件。obj。最后,链接器将该目标代码文件链接到库函数的目标代码,以生成可执行文件程序。exe。
预处理器程序提供预处理器指令,告诉编译器在编译前对源代码进行预处理。所有这些预处理器指令都以“#”(散列)符号开头。“#”符号表示,任何以#开头的语句都将进入预处理器程序,预处理器程序将执行该语句。一些预处理器指令的示例如下: #包括 , #定义 , #ifndef 等等。请记住,#符号只提供一条路径,它将到达预处理器,而include等命令由预处理器程序处理。例如,include将在程序中包含额外的代码。我们可以把这些预处理器指令放在程序的任何地方。
预处理器指令有4种主要类型:
- 宏
- 文件包含
- 条件编译
- 其他指令
现在让我们详细了解每一条指令。
- 宏 :宏是程序中的一段代码,它被赋予了某种名称。每当编译器遇到这个名称时,编译器就会用实际的代码段替换这个名称。“#define”指令用于定义宏。现在让我们借助一个程序来理解宏定义:
C++
#include <iostream> // macro definition #define LIMIT 5 int main() { for ( int i = 0; i < LIMIT; i++) { std::cout << i << "" ; } return 0; } |
C
#include <stdio.h> // macro definition #define LIMIT 5 int main() { for ( int i = 0; i < LIMIT; i++) { printf ( "%d " ,i); } return 0; } |
输出:
01234
在上面的程序中,当编译器执行单词限制时,它会将其替换为5。宏定义中的“限制”一词称为宏模板,“5”是宏扩展。
笔记 :宏定义末尾没有分号(“;”)。宏定义不需要分号来结束。
带参数的宏 :我们还可以将参数传递给宏。用参数定义的宏与函数的工作原理类似。让我们通过一个程序来理解这一点:
C++
#include <iostream> // macro with parameter #define AREA(l, b) (l * b) int main() { int l1 = 10, l2 = 5, area; area = AREA(l1, l2); std::cout << "Area of rectangle is: " << area; return 0; } |
C
#include <stdio.h> // macro with parameter #define AREA(l, b) (l * b) int main() { int l1 = 10, l2 = 5, area; area = AREA(l1, l2); printf ( "Area of rectangle is: %d" , area); return 0; } |
输出:
Area of rectangle is: 50
我们可以从上面的程序中看到,每当编译器在程序中找到区域(l,b),它就会用语句(l*b)替换它。不仅如此,传递到宏模板区域(l,b)的值也将在语句(l*b)中被替换。因此面积(10,5)等于10*5。
- 文件包含 :这种类型的预处理器指令告诉编译器在源代码程序中包含一个文件。用户可以在程序中包含两种类型的文件:
- 头文件还是标准文件 :这些文件包含诸如printf()、scanf()等预定义函数的定义。必须包含这些文件才能使用这些函数。不同的函数在不同的头文件中声明。例如,标准I/O函数位于“iostream”文件中,而执行字符串操作的函数位于“string”文件中。 语法 :
#include< file_name >
哪里 文件名 要包含的文件名。“”括号告诉编译器在标准目录中查找文件。
- 用户定义的文件 :当程序变得非常大时,最好将其划分为较小的文件,并在需要时包含。这些类型的文件是用户定义的文件。这些文件可以包括:
#include"filename"
- 条件编译 :条件编译指令是有助于编译程序特定部分或基于某些条件跳过编译程序特定部分的指令类型。这可以通过两个预处理命令的帮助来完成 条件编译 “还有” 恩迪夫 ‘. 语法 :
#ifdef macro_name statement1; statement2; statement3; . . . statementN;#endif
如果名称为的宏 宏名称 ‘则语句块将正常执行,但如果未定义,编译器将跳过该语句块。
- 其他指令 :除上述指令外,还有两条指令不常用。这些是:
- #undef指令 :#unde指令用于取消现有宏的定义。本指令的作用如下:
#undef LIMIT
使用此语句将取消现有宏限制的定义。在此语句之后,每个“#ifdef LIMIT”语句的计算结果都将为false。
- #布拉格指令 :本指令为特殊用途指令,用于开启或关闭某些功能。这类指令是特定于编译器的,也就是说,它们因编译器而异。下面讨论了一些#pragma指令:
- #布拉格创业公司 和 #布拉格出口 :这些指令帮助我们指定在程序启动之前(控件传递到main()之前)和程序退出之前(控件从main()返回之前)需要运行的函数。 注: 下面的程序不能与GCC编译器一起使用。 请看以下节目:
C++
#include <bits/stdc++.h> using namespace std; void func1(); void func2(); #pragma startup func1 #pragma exit func2 void func1() { cout << "Inside func1()" ; } void func2() { cout << "Inside func2()" ; } int main() { void func1(); void func2(); cout << "Inside main()" ; return 0; } // This code is contributed by shivanisinghss2110 |
C
#include <stdio.h> void func1(); void func2(); #pragma startup func1 #pragma exit func2 void func1() { printf ( "Inside func1()" ); } void func2() { printf ( "Inside func2()" ); } int main() { void func1(); void func2(); printf ( "Inside main()" ); return 0; } |
输出:
Inside func1()Inside main()Inside func2()
当在GCC编译器上运行时,上述代码将产生如下所示的输出:
Inside main()
这是因为GCC不支持#pragma启动或退出。但是,您可以在GCC编译器上使用以下代码获得类似的输出。
C++
#include <iostream> using namespace std; void func1(); void func2(); void __attribute__((constructor)) func1(); void __attribute__((destructor)) func2(); void func1() { printf ( "Inside func1()" ); } void func2() { printf ( "Inside func2()" ); } // Driver code int main() { printf ( "Inside main()" ); return 0; } // This code is contributed by Shivani |
C
#include <stdio.h> void func1(); void func2(); void __attribute__((constructor)) func1(); void __attribute__((destructor)) func2(); void func1() { printf ( "Inside func1()" ); } void func2() { printf ( "Inside func2()" ); } int main() { printf ( "Inside main()" ); return 0; } |
- #pragma warn指令: 此指令用于隐藏编译期间显示的警告消息。 我们可以隐藏警告,如下所示:
- #布拉格警告-rvl :本指令隐藏了当本应返回值的函数不返回值时发出的警告。
- #布拉格警告-标准杆 :此指令隐藏函数不使用传递给它的参数时发出的警告。
- #布拉格马警告-rch :此指令隐藏无法访问代码时发出的警告。例如:在 回来 函数中的语句不可访问。
本文由 严酷的阿加瓦尔 .如果你喜欢GeekSforgek,并想贡献自己的力量,你也可以使用 写极客。组织 或者把你的文章寄到contribute@geeksforgeeks.org.看到你的文章出现在Geeksforgeks主页上,并帮助其他极客。
如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写下评论。