C++预编译头文件 – stdafx.h
预编译头文件的由来
也许请教了别的高手之后,他们会告诉你,这是预编译头,必须包含。可是,这到底是为什么呢?预编译头有什么用呢?
咱们从头文件的编译原理讲起。其实头文件并不神秘,其在编译时的作用,就是把自己的所有内容直接“粘贴”到相应的 #include 语句处。其实,编译器在编译你的程序的时候,所做的第一件事,也就是展开所有的 #include 语句和 #define 语句。
头文件的出现,固然给书写程序带来了很大方便。可是到了 Windows 时代后,慢慢就呈现出一些问题了。几乎所有的 Windows 程序都必须包含 windows.h,而那个文件却硕大无比,将它展开后往所有文件中一粘贴,编译的时候立刻慢得像只蜗牛。
到了 MFC 时代后,情况更为恶劣了。毕竟 C 风格的 Windows 头文件里面包含的还仅仅是函数定义和宏,编译难度不算太大,而 MFC 库里面的头文件可都是类声明啊!更何况,一个最简单的工程,都会生成大量的类,需要用到大量的函数。如果工程稍微复杂一些,编译难度可想而知!
但是,人们惊奇地发现,虽然用到的头文件又多又杂,但是在一个工程中,总有那么一堆头文件,是几乎所有 cpp 都必须包含的。那么,可不可以把这些头文件提取出来,只编译一编,然后所有其它 cpp 就都能使用呢?没错,这就是预编译头的思想都由来!
实践证明,使用了预编译头技术后,编译速度大大提高了。可以到你的工程目录下的Debug 或 Release 目录中看一看,里面有一个体积极为硕大的 .pch 文件,那就是传说中的“编译之后的预编译头”。
使用了预编译头技术后,虽然带来了极大地方便,但也造成了一个问题:由于它假定预编译头中包含过的头文件会在所有 cpp 中使用,因此它在编译你的 cpp 的时候,就会将预编译头中已经编译完的部分加载到内存中。如果它突然发现你的 cpp 居然没有包含预编译头,它就会很郁闷,因为它不知道该如何将已编译完的部分从内存中请出去,整个编译过程就会失败。
因此,如果你使用了预编译头技术,就必须在所有的 cpp 中包含预编译头。MFC 工程中为你建立了一个默认的预编译头 stdafx.h,如果你愿意,也可以在自己的工程中使用其它文件名作为你的预编译头,如果你觉得有必要。
预编译头的概念
所谓的预编译头就是把一个工程中的那一部分代码,预先编译好放在一个文件里(通常是以.pch为扩展名的),这个文件就称为预编译头文件。这些预先编译好的代码可以是任何的C/C++代码 – 甚至是inline的函数,但是必须是稳定的,在工程开发的过程中不会被经常改变。如果这些代码被修改,则需要重新编译生成预编译头文件。注意生成预编译头文件是很耗时间的。同时你得注意预编译头文件通常很大,通常有10M+大。注意及时清 理那些没有用的预编译头文件。
也许你会问:现在的编译器都有Time stamp的功能,编译器在编译整个工程的时候,它只会编译那些经过修改的文件,而不会去编译那些从上次编译过,到现在没有被修改过的文件。那么为什么还要预编译头文件呢?答案是,我们知道编译器是以文件为单位编译的,一个文件经过修改后,会重新编译整个文件,当然在这个文件里包含的所有头文件中的东西都要重新处理一遍。VC的预编译头文件保存的正是这部分信息。以避免每次都要重新处理这些头文件。
预编译头的作用
Windows和MFC的include文件都非常大,即使有一个快速的处理程序,编译程序也要花费相当长的时间来完成工作。由于每个.CPP文件都包含相同的include文件,为每个.CPP文件都重复处理这些文件就显得很傻了。
为避免这种浪费,AppWizard和VisualC++编译程序一起进行工作,如下所示:
- AppWizard建立了文件stdafx.h,该文件包含了所有当前工程文件需要的MFCinclude文件。且这一文件可以随被选择的选项而变化。
- AppWizard然后就建立Stdafx.cpp。这个文件通常都是一样的。(只有一句 #include “stdafx.h”, 因为仅仅只有头文件的话是不能参与编译的)
- 然后AppWizard就建立起工程文件,这样第一个被编译的文件就是stdafx.cpp。
- 当VisualC++编译stdafx.cpp文件时,它将结果保存在一个名为projectname.pch的文件里。(扩展名pch表示预编译头文件。)
- 当VisualC++编译随后的每个.cpp文件时,它阅读并使用它刚生成的.pch文件。VisualC++不再分析Windowsinclude文件,除非你又编辑了stdafx.cpp或stdafx.h。
- 你编写的任何.cpp文件都必须首先包含stdafx.h。
- 如果你有工程文件里的大多数.cpp文件需要.h文件,顺便将它们加在stdafx.h(后部)上,然后预编译stdafx.cpp。
- 由于.pch文件具有大量的符号信息,它是你的工程文件里最大的文件。
C++预编译头文件 – stdafx.h的更多相关文章
- 预编译头文件 StdAfx.h
预编译头文件: 最常见的使用场景就是 StdAfx.h 文件,在这个文件中包含常用的头文件,比如windows.h,cstdio,string,别的 .cpp 文件去包含 StdAfx.h 头文件.编 ...
- 预编译头文件stdafx.h-stdafx.cpp-stdafx.pch(pre-compile headfile)
tdafx的英文全称为:Standard Application Framework Extensions(标准应用程序框架的扩展). 所谓头文件预编译,就是把一个工程(Project)中使用的一些M ...
- 预编译头文件pch
1. 预编译头文件 作用:提高编译效率.预编译头文件(扩展名为.PCH),是为了提高编译效率而使用的一种方法,把一个工程中较稳定的代码预先编译好放在一个文件(.PCH)里.避免每次编译 ...
- Visual Studio中头文件stdafx.h的作用
在较新版的Visual Studio中,新生成的C++项目文件的的头文件夹下会默认有头文件stdafx.h,而源文件夹下则默认有源文件stdafx.cpp,手动将这些文件删除后,编译时系统还会报错.下 ...
- VS2010遇到fatal error C1083: 无法打开预编译头文件:“xxx.pch”: No such file or directory
对C++和VS2010非常不熟悉,但是无奈赶着项目,只能看了点基础就上手,然后就碰到这个问题了. 原因分析: http://bbs.csdn.net/topics/340191697?page=1 编 ...
- fatal error C1083: 无法打开预编译头文件:“Debug\a.pch”:No such file or directory
一.解决方法 右键点击你创建的项目,选择“属性标签”点击属性,弹出“项目属性页”,在左侧找到以下位置 配置属性 --> C/C++ --> 预编译头,并选择它:在右边的菜单中选择 “ ...
- C++ 预编译头文件
1.解决什么问题? C++ 编译器是单独,分别编译的,每个cpp文件,进行预编译(也就是对#include,define 等进行文本替换),生成编译单元.编译单元是一个自包含文件,C++编译器对编译单 ...
- 【转】预编译头文件来自编译器的早期版本,或者预编译头为 C++ 而在 C 中使用它(或相反)
用VC++ 2008 编写C语言程序,编译出现错误: 预编译头文件来自编译器的早期版本,或者预编译头为 C++ 而在 C 中使用它(或相反) 解决方法: 建工程时 建立空项目 或者在项目设置里关闭预编 ...
- VS2005 MFC 预编译头文件来自编译器的早期版本,或者预编译头为 C++ 而在 C 中使用它(或相反)
当 Visual C++ 项目启用了预编译头 (Precompiled header) 功能时,如果项目中同时混合有 .c 和 .cpp 源文件,则可能收到 C1853 编译器错误:fatal err ...
随机推荐
- ARMV8体系结构简介
armv8 1.前言 本文的主要内容来源于ARMV8白皮书v5,对ARMV8做一个概述.包含如下的内容: 首先从背景谈起,讲述ARM的发展历程: 之后介绍ARMV8体系结构的基本特征: 介绍A64指令 ...
- python3 re模块正则匹配字符串中的时间信息
匹配时间: # -*- coding:utf-8 -*- import re def parseDate(l): patternForTime = r'(\d{4}[\D]\d{1,2}[\D]\d{ ...
- 周一04.3流程控制while循环
#循环就是重复做某件事 1.条件循环:while,语法如下 while 条件: # 循环体 # 如果条件为真,那么循环体则执行,执行完毕后再次循环,重新判断条件... # 如果条件为假,那么循环体不执 ...
- MyBatis学习日记(一):拜见小主——MyBatis
近日学习MyBatis,特将学习过程及一点心得记录于此. MyBatis为何物? MyBatis 是支持定制化SQL.存储过程以及高级映射的优秀的持久层框架.MyBatis 避免了几乎所有的 JDBC ...
- Generetor函数与线程之间的思考
在解析这个问题之前,首先,我们来了解一下es6标准里新增解决异步的两种规范 Promise与Generetor Promise 其实Promise的本质 还是基于js程式的回调处理----这一点看它的 ...
- 查看linux的公网地址
在搭建环境时,我们需要搭建公网IP地址,因此我们可以使用以下命令查看公网IP地址 curl ifconfig.me 同时我们可以通过以下命令查看公网地址 curl cip.cc
- JS JavaScript模块化(ES Module/CommonJS/AMD/CMD)
前言 前端开发中,起初只要在script标签中嵌入几十上百行代码就能实现一些基本的交互效果,后来js得到重视,应用也广泛起来了, jQuery,Ajax,Node.Js,MVC,MVVM等的助力也使得 ...
- windows配置nginx实现负载均衡集群 -请求分流
windows配置nginx实现负载均衡集群 一.windows上安装nginx 1.下载nginx的windows版本http://nginx.org/en/download.html 2.把压缩文 ...
- 安装Cnario提示.Net 3.5安装错误, 检查Windows系统更新提示无法检查到更新, 安装.Net 3.5提示"Windows无法完成请求的更改, 错误代码:0x800F081F"
症状: Windows检查系统更新时提示无法完成, 尝试安装.Net 3.5等组件时都无法完成, 错误代码: 0x800F081F 原因: 可能时设置了禁止Windows自动更新, 需要重新打开 解决 ...
- 360大牛:全面解读PHP面试
让大家了解基本面试流程和面试的核心要求以及意义是什么并理解PHP面试考点主要以基础为核心,说明PHP面试考察范围. 有需要联系:QQ:1844912514