我们先来了解下stdafx.h,然后才方便了解为何iostream要放在stdafx.h之后。

一、先说stdafx.h(来自:C++头文件的包含顺序研究

在Visual Studio环境下开发我们发现几乎每个cpp文件都要包含stdafx.h这个文件,而且要把它放在最前面的位置,否则就会出错。这是为什么呢?

原来Visual Studio采用一种预编译的机制。要了解预编译机制,先介绍一下预编译头。所谓的预编译头就是把一个工程中的那一部分代码,预先编译好放在一个文件里(通常是以.pch为扩展名的),这个文件就称为预编译头文件这些预先编译好的代码可以是任何的C/C++代码,甚至是inline的函数,但是必须是稳定的,在工程开发的过程中不会被经常改变。如果这些代码被修改,则需要重新编译生成预编译头文件。注意生成预编译头文件是很耗时间的。同时你得注意预编译头文件通常很大,通常有6- 7M大。注意及时清理那些没有用的预编译头文件。

也许你会问:现在的编译器都有Time stamp的功能,编译器在编译整个工程的时候,它只会编译那些经过修改的文件,而不会去编译那些从上次编译过,到现在没有被修改过的文件。那么为什么还要预编译头文件呢?答案在这里,我们知道编译器是以文件为单位编译的,一个文件经过修改后,会重新编译整个文件,当然在这个文件里包含的所有头文件中的东西(.eg Macro, Preprocessor )都要重新处理一遍。 VC的预编译头文件保存的正是这部分信息。以避免每次都要重新处理这些头文件。

根据上文介绍,预编译头文件的作用当然就是提高便宜速度了,有了它你没有必要每次都编译那些不需要经常改变的代码。编译性能当然就提高了。

要使用预编译头,我们必须指定一个头文件,这个头文件包含我们不会经常改变的代码和其他的头文件,然后我们用这个头文件来生成一个预编译头文件(.pch 文件)想必大家都知道StdAfx.h这个文件。很多人都认为这是VC提供的一个“系统级别”的,编译器带的一个头文件。其实不是的,这个文件可以是任何名字的。我们来考察一个典型的由AppWizard生成的MFC Dialog Based 程序的预编译头文件。(因为AppWizard会为我们指定好如何使用预编译头文件,默认的是StdAfx.h,这是VC起的名字)。我们会发现这个头文件里包含了以下的头文件:

  1. #include <afxwin.h> // MFC core and standard components
  2. #include <afxext.h> // MFC extensions
  3. #include <afxdisp.h> // MFC Automation classes
  4. #include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
  5. #include <afxcmn.h>

这些正是使用MFC的必须包含的头文件,当然我们不太可能在我们的工程中修改这些头文件的,所以说他们是稳定的。

那么我们如何指定它来生成预编译头文件。我们知道一个头文件是不能编译的。所以我们还需要一个cpp文件来生成.pch 文件。这个文件默认的就是StdAfx.cpp。在这个文件里只有一句代码就是:#include“Stdafx.h”。原因是理所当然的,我们仅仅是要它能够编译而已―――也就是说,要的只是它的.cpp的扩展名。我们可以用/Yc编译开关来指定StdAfx.cpp来生成一个.pch文件,通过/Fp 编译开关来指定生成的pch文件的名字。打开project ->Setting->C/C++ 对话框。把Category指向Precompiled Header。在左边的树形视图里选择整个工程,Project Options(右下角的那个白的地方)可以看到 /Fp “debug/PCH.pch”,这就是指定生成的.pch文件的名字,默认的通常是 <工程名>.pch。然后,在左边的树形视图里选择 StdAfx.cpp,这时原来的Project Option变成了 Source File Option(原来是工程,现在是一个文件,当然变了)。在这里我们可以看到 /Yc开关,/Yc的作用就是指定这个文件来创建一个Pch文件。/Yc后面的文件名是那个包含了稳定代码的头文件,一个工程里只能有一个文件的可以有 YC开关。VC就根据这个选项把 StdAfx.cpp编译成一个Obj文件和一个PCH文件。

这样,我们就设置好了预编译头文件。也就是说,我们可以使用预编译头功能了。以下是注意事项:

1)如果使用了/Yu,就是说使用了预编译,我们在每个.cpp文件的最开头,包含你指定产生pch文件的.h文件(默认是stdafx.h)不然就会有问题。如果你没有包含这个文件,就告诉你Unexpected file end.

2)如果你把pch文件不小心丢了,根据以上的分析,你只要让编译器生成一个pch文件就可以了。也就是说把stdafx.cpp(即指定/Yc的那个cpp文件)重新编译一遍就可以了。

二、为何iostream要放在stdafx.h之后(来自:stdafx.h为什么要放在iostream的前面

stdafx.h名称的英文全称为:Standard Application Framework Extensions   

所谓头文件预编译,就是把一个工程(Project)中使用的一些MFC标准头文件(如Windows.H、Afxwin.H)预先编译,以后该工程编译时,不再编译这部分头文件,仅仅使用预编译的结果。这样可以加快编译速度,节省时间。   

预编译头文件通过编译stdafx.cpp生成,以工程名命名,由于预编译的头文件的后缀是“pch”,所以编译结果文件是projectname.pch。  

  编译器通过一个头文件stdafx.h来使用预编译头文件。stdafx.h这个头文件名是可以在project的编译设置里指定的。编译器认为,所有在指令#include "stdafx.h"前的代码都是预编译的,它跳过#include "stdafx. h"指令,使用projectname.pch编译这条指令之后的所有代码。   

因此,所有的MFC实现文件第一条语句都是:#include "stdafx.h"。

参考:

stdafx.h为什么要放在iostream的前面

C++头文件的包含顺序研究

stdafx.h作用以及include中为何iostream必须放在stdafx.h之后?相关推荐

  1. c语言中的头文件stdlib.h的作用,C语言中你可能不熟悉的头文件(stdlib.h)

    C语言中你可能不熟悉的头文件(stdlib.h) C Standard General Utilities Library (header) C标准通用工具库(头文件) 此头文件定义了一些通用功能函数 ...

  2. Linux中使用iOStream头文件,在Linux中使用gcc链接iostream.h

    我想在Linux(Linux MINT 8)中运行我的第一个C++程序.我使用gcc或g++,两者都有相同的问题:编译器找不到我要导入的库. 我怀疑我应该复制工作文件夹中的iostream.h文件(我 ...

  3. 51单片机c语言头文件大全,51单片机keilC中头文件absacc.h作用

    当51单片机通过8255和锁存器74LS273来扩展IO时,经常用到头文件absacc.h. 在程序中,用"#include"即可使用其中定义的宏来访问绝对地址,包括:CBYTE. ...

  4. C\C++中头文件string与string.h的区别

    http://www.cnblogs.com/Cmpl/archive/2012/01/01/2309710.html 在C++中,#include<iostream>与#include& ...

  5. [转]C++中的头文件和源文件 .h .cpp

    头文件放声明,源文件放具体定义. 原文: http://www.cnblogs.com/lidabo/archive/2012/04/17/2454568.html 一.C++编译模式 通常,在一个C ...

  6. ROS报错:/usr/include/eigen3/Eigen/src/Core/util/StaticAssert.h:119:9: error: ‘YOU_MIXED_DIFFERENT

    本机环境:window10+vmware+ubuntu16.04+kinetic   最近跑了跑ORB-SLAM的示例,配置环境按照ORB-SLAM github上的要求依次下载几个包,再按照在Ubu ...

  7. Unix网络编程unp.h问题以及Linux中的库

    Stevens的<UNIX网络编程 卷1:套接字连网API>是一本很著名的UNIX网络编程书籍.其中使用了一个unp.h的引用,如果没有设置相应的库的话,即使引入了头文件也是没用的.所以首 ...

  8. 【致敬嵌入式攻城狮第2期活动预热征文】解决瑞萨RA2E1开发板在RT-Thread的版本中编译报错 error: ‘board_cfg.h‘ file not found

    解决瑞萨RA2E1开发板在RT-Thread的版本中编译报错 error: 'board_cfg.h' file not found 继上上周在RA2E1开发板上跑通了RT-Thread最新版本的代码 ...

  9. G:\Windows Kits\10\include\10.0.18362.0\ucrt\inttypes.h(96): error C2143: 语法错误: 缺少“{”(在“__cdecl”的前面)

    (1)本机上安装了Microsoft Visual Studio2017 Community版 A.将D:\Program Files (x86)\Microsoft Visual Studio\20 ...

  10. c程序:定义函数areaZ,功能是求圆锥体积。在主函数中输入半径r和高h,调用函数areaZ求体积,并在主函数中输出圆锥的体积,其中变量r,h均为double型数据。(公式v=h*3.14*r2/3)

    /*定义函数areaZ,功能是求圆锥体积.在主函数中输入半径r和高h,调用函数areaZ求体积,并在主函数中输出圆锥的体积,其中变量r,h均为double型数据.(公式v=h*3.14*r2/3)*/ ...

最新文章

  1. 传智播客java基础的习题_传智播客java基础班(集合与IO)阶段测试题
  2. python批量读取文件内容_Python 文本文件内容批量抽取实例
  3. 分布式一致Hash算法
  4. matlab消去前一个图,各位matlab高手,如何从2个3元方程中消去一个变量,然后做3维图形~...
  5. Spring Data ElasticSearch删除索引遇到的java.lang.IllegalStateException: Failed to load ApplicationContext异常
  6. Marketing Cloud API消费entity unsupported format错误消息的处理
  7. Docverter – 文本文件轻松转换为 PDF,Docx 和 ePub 文件
  8. 异步通信在生活中的例子_AJAX简单异步通信实例分析
  9. linux怎么查看定时任务有没有运行,怎么看crontab定时任务是否执行
  10. 编写适合于自己的代码生成器 (zhuan)
  11. IE6的3像素神奇bug:缘起与解决方案
  12. 笨猪猪:“暹粒游记”(下)
  13. android 基础布局
  14. Flash游戏破解参考
  15. 解读《美国国家BIM标准》– BIM能力成熟度模型(六)
  16. 【清华大学陈渝】第四章_物理内存管理
  17. 带手续费买卖股票的最大利益[找DP的状态定义到底缺什么?]
  18. 2021-12-12
  19. 平台交叉打包 GYP
  20. Excel如何将多列数据按行合并

热门文章

  1. UE4--地形篇——风吹草动的草
  2. Android源码下载地址
  3. Node.js内存泄漏分析
  4. 计算机数据结构模拟试题,十套计算机数据结构试题及答案.doc
  5. java 钩子程序,在kill 的时候程序平滑退出
  6. 【Echarts】地图 中国城市经纬度Json
  7. Extjs EditorGridPanel复选框实现单选, 同时锁住指定行
  8. Rainmeter雨滴天气-(永不过时版通过获取网页数据实现)
  9. linux下的经典软件总结
  10. php日历表代码,PHP输出日历表代码实例