vs2017自動生成的#include“stdafx.h”詳解及解決方案


vs2017自動生成的#include“stdafx.h”詳解及解決方案

 

問題描述:

在高版本的Visual Studio的默認設置中,會出現這么一個現象,在新建項目之后,項目會自動生成#include“stdafx.h”的頭文件,而且刪掉之后,即使是自己正常編寫的程序也會顯示出錯:

(關於黑/深色主題,主要是為了在長時間使用電腦的時候保護眼睛,具體設置也很簡單,可以參見我另外一篇文章:)

問題解決:

實際上#include“stdafx.h”是為了方便,包含了很多頭文件的頭文件,叫做預編譯頭。這個操作在工程很大,頭文件很多的時候用起來很方便。dr我們也可以設置默認不使用預編譯頭,設置過程如下:

1.選擇【項目】-【屬性】-【C/C++】-【預編譯頭】-【創建/使用預編譯頭】

可以看到有3個選項:【創建預編譯頭】、【使用預編譯頭】和【不使用預編譯頭】。

想要取消VS2017自動生成的#include“stdafx.h”,只要將選項改為:【不使用預編譯頭】就行了。

 

============================================================================

以下為轉載內容(轉載自https://blog.csdn.net/qingkong8832/article/details/6695123):

1,用VS2017新建項目,選擇【Win32】-【Win32控制台應用程序】-輸入名稱:Test-【確定】

  再選【下一步】-默認情況下,我們都是在【空項目】前打上對勾,建立一個純的C或C++程序。

我們這里選擇默認,即【預編譯頭】前打上對勾,之后【完成】

2,在Test項目中,頭文件有stdafx.h和targetver.h,源文件有stdafx.cpp和Test.cpp,還有一個ReadMe.txt文件。

3,默認的主函數為

  1. #include "stdafx.h"  
  2.   
  3.   
  4. int _tmain(int argc, _TCHAR* argv[])  
  5. {  
  6.     return 0;  
  7. }  


和我們一般的寫的程序不一樣,我們一般會寫成下面的形式:

  1. #include  <stdio.h>  
  2.   
  3. int main()  
  4. {  
  5.        return 0;  
  6. }  


4,我們要糾結,這里怎么沒有了stdio.h了呢,取而代之的是stdafx.h呢?

我們打開stdafx.h文件,如下:

  1. // stdafx.h : 標准系統包含文件的包含文件,  
  2. // 或是經常使用但不常更改的  
  3. // 特定於項目的包含文件  
  4. //  
  5.   
  6. #pragma once  
  7.   
  8. #include "targetver.h"  
  9.   
  10. #include <stdio.h>  
  11. #include <tchar.h>  
  12.   
  13.   
  14.   
  15. // TODO: 在此處引用程序需要的其他頭文件  


可以看到,這里包含了stdio.h庫文件,為什么包含到這里呢?我們先不急着解答。

先看看,stdafx.cpp文件:

  1. // stdafx.cpp : 只包括標准包含文件的源文件  
  2. // Test.pch 將作為預編譯頭  
  3. // stdafx.obj 將包含預編譯類型信息  
  4.   
  5. #include "stdafx.h"  
  6.   
  7. // TODO: 在 STDAFX.H 中  
  8. // 引用任何所需的附加頭文件,而不是在此文件中引用  


這里面只有包含的庫文件,沒有操作,它是做什么用的呢?

在ReadMe.txt中,我們看到這么一段話:

其他標准文件:
StdAfx.h, StdAfx.cpp
這些文件用於生成名為 Test.pch 的預編譯頭 (PCH) 文件和名為 StdAfx.obj 的預編譯類型文件。

原來是生成預編譯頭文件!

5,百科上參看下:

  1. 一、什么是預編譯頭?   
  2.   所謂預編譯頭,就是把頭文件事先編譯成一種二進制的中間格式,供后續的編譯過程使用。預編譯頭物理上與通常的的.obj文件是一樣的,但是千萬不要把這個中間格式與. o/.obj/.a/.lib的格式混淆,他們是截然不同的!所以預編譯頭文件的特性和目標文件也不同(盡管他們都屬於某種中間文件)。編譯入預編譯頭的.h,.c,.cpp文件在整個編譯過程中,只編譯一次,如預編譯頭所涉及的部分不發生改變的話,在隨后的編譯過程中此部分不重新進行編譯。進而大大提高編譯速度,並便於對頭文件進行管理,也有助於杜絕重復包含問題。——但也有類似的地方的,比如,它們都是編譯器之間不兼容的^_^,就是說你不能把VC生成的預編譯頭拿到GCC上去用。甚至擴展名都不一樣,VC的是大家都熟悉的. pch,而GCC的,是.gch。   
  3. 二、什么時候使用預編譯頭?   
  4.   當大多.c或.cpp文件都需要相同的頭文件時。   
  5.   當某些代碼被大量重復使用時。   
  6.   當導入某些不同庫都有實現的函數,並產生混亂時。  

6,可以知道預編譯,是為了提高編譯速度!

再看下面一段話

 
  1. stdafx.h    
  2.   
  3. 1名稱的英文全稱為:Standard Application Fram Extend  
  4.   所謂頭文件預編譯,就是把一個工程(Project)中使用的一些MFC標准頭文件(如Windows.H、Afxwin.H)預先編譯,以后該工程編譯時,不再編譯這部分頭文件,僅僅使用預編譯的結果。這樣可以加快編譯速度,節省時間。   
  5.   預編譯頭文件通過編譯stdafx.cpp生成,以工程名命名,由於預編譯的頭文件的后綴是“pch”,所以編譯結果文件是projectname.pch。   
  6.   編譯器通過一個頭文件stdafx.h來使用預編譯頭文件。stdafx.h這個頭文件名是可以在project的編譯設置里指定的。編譯器認為,所有在指令#include "stdafx.h"前的代碼都是預編譯的,它跳過#include "stdafx. h"指令,使用projectname.pch編譯這條指令之后的所有代碼。   
  7.   因此,所有的MFC實現文件第一條語句都是:#include "stdafx.h"。  
  8.   
  9. 2 詳細工作原理及作用  
  10.   stdafx.h中沒有函數庫,只是定義了一些環境參數,使得編譯出來的程序能在32位的操作系統環境下運行。   
  11.   Windows和MFC的include文件都非常大,即使有一個快速的處理程序,編譯程序也要花費相當長的時間來完成工作。由於每個.CPP文件都包含相同的include文件,為每個.CPP文件都重復處理這些文件就顯得很傻了。   
  12.   為避免這種浪費,AppWizard和VisualC++編譯程序一起進行工作,如下所示:   
  13.   ◎AppWizard建立了文件stdafx.h,該文件包含了所有當前工程文件需要的MFCinclude文件。且這一文件可以隨被選擇的選項而變化。   
  14.   ◎AppWizard然后就建立stdafx.cpp。這個文件通常都是一樣的。   
  15.   ◎然后AppWizard就建立起工程文件,這樣第一個被編譯的文件就是stdafx.cpp。   
  16.   ◎當VisualC++編譯stdafx.cpp文件時,它將結果保存在一個名為stdafx.pch的文件里。(擴展名pch表示預編譯頭文件。)   
  17.   ◎當VisualC++編譯隨后的每個.cpp文件時,它閱讀並使用它剛生成的.pch文件。VisualC++不再分析Windowsinclude文件,除非你又編輯了stdafx.cpp或stdafx.h。   
  18.   這個技術很精巧,你不這么認為嗎?(還要說一句,Microsoft並非是首先采用這種技術的公司,Borland才是。)在這個過程中你必須遵守以下規則:   
  19.   ◎你編寫的任何.cpp文件都必須首先包含stdafx.h。   
  20.   ◎如果你有工程文件里的大多數.cpp文件需要.h文件,順便將它們加在stdafx.h(后部)上,然后預編譯stdafx.cpp。   
  21.   ◎由於.pch文件具有大量的符號信息,它是你的工程文件里最大的文件。   
  22.   如果你的磁盤空間有限,你就希望能將這個你從沒使用過的工程文件中的.pch文件刪除。執行程序時並不需要它們,且隨着工程文件的重新建立,它們也自動地重新建立。  

要點:(1), Windows和MFC的include文件都非常大,即使有一個快速的處理程序,編譯程序也要花費相當長的時間來完成工作。由於每個.CPP文件都包含相同的include文件,為每個.CPP文件都重復處理這些文件就顯得很傻了。 

(2),MFC中,你編寫的任何.cpp文件都必須首先包含stdafx.h。

(3),由於.pch文件具有大量的符號信息,它是你的工程文件里最大的文件,不需要的時候可以刪除。

 

7,我們可以自己設置自己的預編譯文件,不一定非要是stdafx.h

右擊stdafx.cpp文件,選擇【屬性】-【C/C++】-【預編譯頭】-【創建/使用預編譯頭】

可以看到有3個選項:【創建預編譯頭】、【使用預編譯頭】和【不使用預編譯頭】。

stdafx.cpp肯定選擇的是【創建預編譯頭】

============================================================================

再右擊Test.cpp文件,選擇【屬性】-【C/C++】-【預編譯頭】-【創建/使用預編譯頭】

可見,它選擇的是【使用預編譯頭】,下面選的文件是StdAfx.h文件,最下面指明的是pch文件的路徑

================================================================================

如何創建自己的預編譯文件,其實過程正如上面我們講的過程。

如果工程很大,頭文件很多,而有幾個頭文件又是經常要用的,那么 

1,把這些頭文件全部寫到一個頭文件里面去,比如寫到preh.h 

2,寫一個preh.c,里面只一句話:#include "preh.h" ,為了生存pch預編譯文件

3,對於preh.c,在【屬性】里面設置【創建預編譯頭】,對於其他.c文件,設置【使用預編譯頭】

 

===================== End

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM