首先记住一个点:
预处理器在.cpp中遇到#include<> 或者 #include " ", 都会将#include<> 或者 #include " "指令替换为他们包含的头文件中的内容,形成 .i文件。
举个栗子, 如下代码
/ *WaLib.h */
#pragma once
int add(int x,int y);
/ *WaLib.cpp */
//#include "stdafx.h"
#include "WaLib.h"
int add(int x, int y)
{
return x + y;
}
/ *targetver.h */
#pragma once
int div(int x,int y)
{
return x - y;
}
ConsoleApplication1.cpp中调用代码如下:
// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
#include "targetver.h"
#include "WaLib.h"
int main()
{
return 0;
}
Tip:如何查看预处理后文件?
1、右键工程(例子中是myproject),选择【属性】,在弹出的对话框中,选择【配置属性】-->【C/C++】-->【预处理器】,将【预处理到文件】该为【是】,应用,确认。
2、在VS 的菜单栏中点击【生成】-->【生成myproject】 我这个例子中是myproject,依据你的工程名是什么就是什么。
3、右键 【myproject】--->【在文件资源管理器中打开文件夹】---> 在Debug目录下有个 xx.i 文件,就是预处理后的文件。
预处理结果如下:
/ *WaLib.i */
#line 1 "e:\\develop\\consoleapplication1\\consoleapplication1\\walib.cpp"
#line 1 "e:\\develop\\consoleapplication1\\consoleapplication1\\walib.h"
#pragma once
int add(int x,int y);
#line 3 "e:\\develop\\consoleapplication1\\consoleapplication1\\walib.cpp"
int add(int x, int y)
{
return x + y;
}
/ *ConsoleApplication1.i */
#line 1 "e:\\develop\\consoleapplication1\\consoleapplication1\\consoleapplication1.cpp"
#line 1 "e:\\develop\\consoleapplication1\\consoleapplication1\\targetver.h"
#pragma once
int div(int x,int y)
{
return x - y;
}
#line 4 "e:\\develop\\consoleapplication1\\consoleapplication1\\consoleapplication1.cpp"
#line 1 "e:\\develop\\consoleapplication1\\consoleapplication1\\walib.h"
#pragma once
int add(int x,int y);
#line 5 "e:\\develop\\consoleapplication1\\consoleapplication1\\consoleapplication1.cpp"
int main()
{
return 0;
}
总结
1、预处理器在.cpp中遇到#include<> 或者 #include " ", 都会将#include<> 或者 #include " "指令替换为他们包含的头文件中的内容,形成 .i文件。这就是预处理器对头文件的处理结果。
2、头文件只在预处理期起作用,预处理过后生成 .i 文件,此后头文件就没有作用了。
3、预处理指令 的 作用域 为 源文件作用域,也就是每 一条 预处理指令 只在它所在的 .cpp文件有效。
4、预处理不属于任何名称空间,名称空间“管不住”预处理指令。预处理指令不受C/C++的作用域规则,它是一种编译前期的机制。
5、用户将一个源文件( .c 或者 .cpp ) 提交给编译器后,首先执行的是该文件的预处理(处理源文件中的预处理指令),预处理后的结果为编译单元,这种编译单元才是编译器真正 工作的对象!程序员眼中看见的是 源文件(.c 或者 .cpp )和头文件, 而编译器眼中只有编译单元(预处理后形成的.i文件)。但是我 们口头上说的C/C++编译器包括预处理器。
防止头文件重复包含
当项目大了后,编译单元之间的关系变得复杂,就很可能出现头文件重复包含的情况。虽然大多是情况下,重复包含头文件是没有问题的,但是这会使.i文件膨胀 。C/C++遵循单定义,多声明的规则。声明多次没问题,但是不必要的声明除了在利于代码阅读外的目的下使用外,其他的要尽量避免。一般采用以下方法。
#ifndef _XXX_H__
#define _XXX_H__
//被包含内容放中间
#endif
C++提供了#pragma once 预处理指令来达到上述效果。
C/C++ 程序编译流程
单文件编译流程
多文件编译流程
参考链接
1、https://www.cnblogs.com/lulipro/p/5976601.html