當前位置:首頁 » 編程軟體 » 頭文件預編譯指令

頭文件預編譯指令

發布時間: 2022-05-29 12:00:30

1. 在C++語言中,包含頭文件的預處理命令以什麼開頭


預處理指令
總是佔用源代碼中的單獨一行,並且
總是以
#
字元和預處理指令名稱開頭
。#
字元的前面以及
#
字元與指令名稱之間可以出現空白符。

包含
#define

#undef
、#if、#elif、#else、
#endif

#line
指令的源代碼行可以用
單行注釋
結束。在包含預處理指令的源行上不允許使用帶
分隔符
的注釋(/*
*/
樣式的注釋)。

預處理指令既不是標記,也不是
C#
句法文法的組成部分。但是,可以用預處理指令包含或排除標記序列,並且可以以這種方式影響
C#
程序的含義。

2. 關於c語言頭文件編譯和運行的問題

1、只要在程序開頭加入#include<頭文件名>,在編譯過程當中,頭文件自動會被添加到源文件當中一起進行編譯。
2、編譯,編譯程序讀取源程序(字元流),對之進行詞法和語法的分析,將高級語言指令轉換為功能等效的匯編代碼,再由匯編程序轉換為機器語言,並且按照操作系統對可執行文件格式的要求鏈接生成可執行程序。
C源程序頭文件-->預編譯處理(cpp)-->編譯程序本身-->優化程序-->匯編程序-->鏈接程序-->可執行文件。

3. C++ 中stdafx.h是什麼意思

C++中stdafx.h的英文全稱為:Standard Application Fram Extend,中文名為:頭文件預編譯。

stdafx.h在C++中起到的作用是:把C++工程中使用的MFC頭文件預先編譯,以後該工程編譯時,直接使用預編譯的結果,這樣可以加快編譯速度。

C++編譯器通過一個頭文件stdafx.h來使用預編譯頭文件。stdafx.h這個頭文件名可以在project的編譯設置里指定。

編譯器默認所有在指令"stdafx.h"前的代碼都是預編譯,它跳過 "stdafx. h"指令,使用projectname.pch編譯這條指令之後的代碼。

(3)頭文件預編譯指令擴展閱讀

Windows和MFC的include文件都非常大,即使有一個快速的處理程序,編譯程序也要花費相當長的時間來完成工作。

由於每個.CPP文件都包含相同的include文件,為每個.CPP文件都重復處理這些文件就顯得很傻了。為避免這種浪費,AppWizard和VisualC++編譯程序一起進行工作,如下所示:

1、AppWizard建立了文件stdafx.h,該文件包含了所有當前工程文件需要MFCinclude 文件。且這一文件可以隨被選擇的選項而變化。

2、AppWizard然後就建立stdafx.cpp。這個文件通常都是一樣的。

3、然後AppWizard就建立起工程文件,這樣第一個被編譯的文件就是stdafx.cpp。

4當VisualC++編譯stdafx.cpp文件時,它將結果保存在一個名為stdafx.pch的文件里。(擴展名pch表示預編譯頭文件。)

5、當VisualC++編譯隨後的每個.cpp文件時,它閱讀並使用它剛生成的.pch文件。VisualC++不再分析Windowsinclude文件,除非你又編緝了stdafx.cpp或stdafx.h。

4. 頭文件中的 ifndef/define/endif 干什麼用可以用什麼編譯命令

這個是預編譯的命令,是用來防止頭文件重復包含的。大部分系統的頭文件重復包含是沒有問題的,但是有時自己編寫的頭文件重復包含會出現變數或者是函數或者類的重定義,這樣編譯不會通過。

5. 預處理指令#pragma db code是什麼意思

一、作用是設定編譯器的狀態或者是指示編譯器完成一些特定的動作。#pragma指令對每個編譯器給出了一個方法,在保持與C和 C++語言完全兼容的情況下,給出主機或操作系統專有的特徵。依據定義,編譯指示是機器或操作系統專有的,且對於每個編譯器都是不同的。

二、常用的pragma指令的詳細解釋。
1.#pragma once。保證所在文件只會被包含一次,它是基於磁碟文件的,而#ifndef則是基於宏的。
2.#pragma warning。允許有選擇性的修改編譯器的警告消息的行為。有如下用法:
#pragma warning(disable:4507 34; once:4385; error:164) 等價於:
#pragma warning(disable:4507 34) // 不顯示4507和34號警告信息
#pragma warning(once:4385) // 4385號警告信息僅報告一次
#pragma warning(error:164) // 把164號警告信息作為一個錯誤
#pragma warning(default:176) // 重置編譯器的176號警告行為到默認狀態
同時這個pragma warning也支持如下格式,其中n代表一個警告等級(1---4):
#pragma warning(push) // 保存所有警告信息的現有的警告狀態
#pragma warning(push,n) // 保存所有警告信息的現有的警告狀態,並設置全局報警級別為n
#pragma warning(pop) // 恢叢 鵲木 孀刺 趐ush和pop之間所做的一切改動將取消
例如:
#pragma warning(push)
#pragma warning(disable:4705)
#pragma warning(disable:4706)
#pragma warning(disable:4707)
#pragma warning(pop)
在這段代碼後,恢復所有的警告信息(包括4705,4706和4707)。
3.#pragma hdrstop。表示預編譯頭文件到此為止,後面的頭文件不進行預編譯。BCB可以預編譯頭文件以 加快鏈接的速度,但如果所有頭文件都進行預編譯又可能占太多磁碟空間,所以使用這個選項排除一些頭文 件。
4.#pragma message。在標准輸出設備中輸出指定文本信息而不結束程序運行。用法如下:
#pragma message("消息文本")。當編譯器遇到這條指令時就在編譯輸出窗口中將「消息文本」列印出來。
5.#pragma data_seg。一般用於DLL中,它能夠設置程序中的初始化變數在obj文件中所在的數據段。如果未指定參數,初始化變數將放置在默認數據段.data中,有如下用法:
#pragma data_seg("Shared") // 定義了數據段"Shared",其中有兩個變數a和b
int a = 0; // 存儲在數據段"Shared"中
int b; // 存儲在數據段".bss"中,因為沒有初始化
#pragma data_seg() // 表示數據段"Shared"結束,該行代碼為可選的
對變數進行專門的初始化是很重要的,否則編譯器將把它們放在普通的未初始化數據段中而不是放在shared中。如上述的變數b其實是放在了未初始化數據段.bss中。
#pragma data_seg("Shared")
int j = 0; // 存儲在數據段"Shared"中
#pragma data_seg(push, stack1, "Shared2") //定義數據段Shared2,並將該記錄賦予別名stack1,然後放入內部編譯器棧中
int l = 0; // 存儲在數據段"Shared2"中
#pragma data_seg(pop, stack1) // 從內部編譯器棧中彈出記錄,直到彈出stack1,如果沒有stack1,則不做任何操作
int m = 0; // 存儲在數據段"Shared"中,如果沒有上述pop段,則該變數將儲在數據段"Shared2"中
6.#pragma code_seg。它能夠設置程序中的函數在obj文件中所在的代碼段。如果未指定參數,函數將放置在默認代碼段.text中,有如下用法:
void func1() { // 默認存儲在代碼段.text中
}
#pragma code_seg(".my_data1")
void func2() { // 存儲在代碼段.my_data1中
}
#pragma code_seg(push, r1, ".my_data2")
void func3() { // 存儲在代碼段.my_data2中
}
#pragma code_seg(pop, r1)
void func4() { // 存儲在代碼段.my_data1中
}
7.#pragma pack。用來改變編譯器的位元組對齊方式。常規用法為:
#pragma pack(n) //將編譯器的位元組對齊方式設為n,n的取值一般為1、2、4、8、16,一般默認為8
#pragma pack(show) //以警告信息的方式將當前的位元組對齊方式輸出
#pragma pack(push) //將當前的位元組對齊方式放入到內部編譯器棧中
#pragma pack(push,4) //將位元組對齊方式4放入到內部編譯器棧中,並將當前的內存對齊方式設置為4
#pragma pack(pop) //將內部編譯器棧頂的記錄彈出,並將其作為當前的內存對齊方式
#pragma pack(pop,4) //將內部編譯器棧頂的記錄彈出,並將4作為當前的內存對齊方式
#pragma pack(pop,r1) //r1為自定義的標識符,將內部編譯器中的記錄彈出,直到彈出r1,並將r1的值作為當前的內存對齊方式;如果r1不存在,當不做任何操作
8.#pragma comment。將一個注釋記錄放置到對象文件或可執行文件中。
其格式為:#pragma comment( comment-type [,"commentstring"] )。其中,comment-type是一個預定義的標識符,指定注釋的類型,應該是compiler,exestr,lib,linker,user之一。
compiler:放置編譯器的版本或者名字到一個對象文件,該選項是被linker忽略的。
exestr:在以後的版本將被取消。
lib:放置一個庫搜索記錄到對象文件中,這個類型應該與commentstring(指定Linker要搜索的lib的名稱和路徑)所指定的庫類型一致。在對象文件中,庫的名字跟在默認搜索記錄後面;linker搜索這個這個庫就像你在命令行輸入這個命令一樣。你可以在一個源文件中設置多個庫搜索記錄,它們在obj文件中出現的順序與在源文件中出現的順序一樣。
如果默認庫和附加庫的次序是需要區別的,使用/Zl編譯開關可防止默認庫放到object模塊中。
linker:指定一個連接選項,這樣就不用在命令行輸入或者在開發環境中設置了。只有下面的linker選項能被傳給Linker:
/DEFAULTLIB
/EXPORT
/INCLUDE
/MANIFESTDEPENDENCY
/MERGE
/SECTION
(1)/DEFAULTLIB:library
/DEFAULTLIB選項將一個library添加到LINK在解析引用時搜索的庫列表。用/DEFAULTLIB指定的庫在命令行上指定的庫之後和obj文件中指定的默認庫之前被搜索。
忽略所有默認庫(/NODEFAULTLIB)選項重寫/DEFAULTLIB:library。如果在兩者中指定了相同的library名稱,忽略庫(/NODEFAULTLIB:library)選項將重寫/DEFAULTLIB:library。
(2)/EXPORT:entryname[,@ordinal[,NONAME]][,DATA]
使用該選項,可以從程序導出函數以便其他程序可以調用該函數,也可以導出數據。通常在DLL中定義導出。
entryname是調用程序要使用的函數或數據項的名稱。ordinal為導出表的索引,取值范圍在1至65535;如果沒有指定ordinal,則LINK將分配一個。NONAME關鍵字只將函數導出為序號,沒有entryname。DATA 關鍵字指定導出項為數據項。客戶程序中的數據項必須用extern __declspec(dllimport)來聲明。
有三種導出定義的方法,按照建議的使用順序依次為:
源代碼中的__declspec(dllexport)
.def文件中的EXPORTS語句
LINK命令中的/EXPORT規范
所有這三種方法可以用在同一個程序中。LINK在生成包含導出的程序時還要創建導入庫,除非在生成過程中使用了.exp 文件。
LINK使用標識符的修飾形式。編譯器在創建obj文件時修飾標識符。如果entryname以其未修飾的形式指定給鏈接器(與其在源代碼中一樣),則LINK將試圖匹配該名稱。如果無法找到唯一的匹配名稱,則LINK發出錯誤信息。當需要將標識符指定給鏈接器時,請使用Dumpbin工具獲取該標識符的修飾名形式。
(3)/INCLUDE:symbol
/INCLUDE選項通知鏈接器將指定的符號添加到符號表。若要指定多個符號,請在符號名稱之間鍵入逗號(,)、分號(;)或空格。在命令行上,對每個符號需指定一次/INCLUDE:symbol。
鏈接器通過將包含符號定義的對象添加到程序來解析symbol。該功能對於添加不會鏈接到程序的庫對象非常有用。
用該選項所指定的符號將覆蓋通過/OPT:REF對該符號進行的移除操作。
(4)/MANIFESTDEPENDENCY:manifest_dependency
/MANIFESTDEPENDENCY允許你指定位於manifest文件的段的屬性。/MANIFESTDEPENDENCY信息可以通過下面兩種方式傳遞給LINK:
直接在命令行運行/MANIFESTDEPENDENCY
通過#pragma comment
(5)/MERGE:from=to
/MERGE選項將第一個段(from)與第二個段(to)進行聯合,並將聯合後的段命名為to的名稱。
如果第二個段不存在,LINK將段(from)重命名為to的名稱。
/MERGE選項對於創建VxDs和重寫編譯器生成的段名非常有用。
(6)/SECTION:name,[[!]{DEKPRSW}][,ALIGN=#]
/SECTION選項用來改變段的屬性,當指定段所在的obj文件編譯的時候重寫段的屬性集。
可移植的可執行文件(PE)中的段(section)與新可執行文件(NE)中的節區(segment)或資源大致相同。
段(section)中包含代碼或數據。與節區(segment)不同的是,段(section)是沒有大小限制的連續內存塊。有些段中的代碼或數據是你的程序直接定義和使用的,而有些數據段是鏈接器和庫管理器(lib.exe)創建的,並且包含了對操作系統來說很重要的信息。
/SECTION選項中的name是大小寫敏感的。
不要使用以下名稱,因為它們與標准名稱會沖突,例如,.sdata是RISC平台使用的。
.arch
.bss
.data
.edata
.idata
.pdata
.rdata
.reloc
.rsrc
.sbss
.sdata
.srdata
.text
.xdata
為段指定一個或多個屬性。屬性不是大小寫敏感的。對於一個段,你必須將希望它具有的屬性都進行指定;如果某個屬性未指定,則認為是不具備這個屬性。如果你未指定R,W或E,則已存在的讀,寫或可執行狀態將不發生改變。
要對某個屬性取否定意義,只需要在屬性前加感嘆號(!)。
E:可執行的
R:可讀取的
W:可寫的
S:對於載入該段的鏡像的所有進程是共享的
D:可廢棄的
K:不可緩存
P:不可分頁的
注意K和P是表示否定含義的。
PE文件中的段如果沒有E,R或W屬性集,則該段是無效的。
ALIGN=#選項讓你為一個具體的段指定對齊值。
user:放置一個常規注釋到一個對象文件中,該選項是被linker忽略的。
9.#pragma section。創建一個段。
其格式為:#pragma section( "section-name" [, attributes] )
section-name是必選項,用於指定段的名字。該名字不能與標准段的名字想沖突。可用/SECTION查看標准段的名稱列表。
attributes是可選項,用於指定段的屬性。可用屬性如下,多個屬性間用逗號(,)隔開:
read:可讀取的
write:可寫的
execute:可執行的
shared:對於載入該段的鏡像的所有進程是共享的
nopage:不可分頁的,主要用於Win32的設備驅動程序中
nocache:不可緩存的,主要用於Win32的設備驅動程序中
discard:可廢棄的,主要用於Win32的設備驅動程序中
remove:非內存常駐的,僅用於虛擬設備驅動(VxD)中
如果未指定屬性,默認屬性為read和write。
在創建了段之後,還要使用__declspec(allocate)將代碼或數據放入段中。
例如:
//pragma_section.cpp
#pragma section("mysec",read,write)
int j = 0;
__declspec(allocate("mysec"))
int i = 0;
int main(){}
該例中, 創建了段"mysec",設置了read,write屬性。但是j沒有放入到該段中,而是放入了默認的數據段中,因為它沒有使用__declspec(allocate)進行聲明;而i放入了該段中,因為使用__declspec(allocate)進行了聲明。
10.#pragma push_macro與#pragma pop_macro。前者將指定的宏壓入棧中,相當於暫時存儲,以備以後使用;後者將棧頂的宏出棧,彈出的宏將覆蓋當前名稱相同的宏。例如:
#include
#define X 1
#define Y 2
int main() {
printf("%d",X);
printf("\n%d",Y);
#define Y 3 // C4005
#pragma push_macro("Y")
#pragma push_macro("X")
printf("\n%d",X);
#define X 2 // C4005
printf("\n%d",X);
#pragma pop_macro("X")
printf("\n%d",X);
#pragma pop_macro("Y")
printf("\n%d",Y);
}
輸出結果:
1
2
1
2
1
3

6. 頭文件預編譯用什麼

#號是官方定義的,用於和其他類型區別的,不用多考慮,你就看看我給你的鏈接看看官方的說法
條件編譯符號#define ???
#if、#elif、#else 和 #endif 指令提供的條件編譯功能是通過預處理表達式和條件編譯符號來控制的。
conditional-symbol:(條件符號:)
除 true 和 false 外的任何標識符或關鍵字
條件編譯符號有兩種可能的狀態:已定義的或未定義的。在源文件詞法處理開始時,條件編譯符號除非已由外部機制(如命令行編譯器選項)顯式定義,否則是未定義的。當處理 #define 指令時,在指令中指定的條件編譯符號在那個源文件中成為已定義的。此後,該符號就一直保持已定義的狀態,直到處理一條關於同一符號的 #undef 指令,或者到達源文件的結尾。這意味著一個源文件中的 #define 和 #undef 指令對同一程序中的其他源文件沒有任何影響。
當在預處理表達式中引用時,已定義的條件編譯符號具有布爾值 true,未定義的條件編譯符號具有布爾值 false。不要求在預處理表達式中引用條件編譯符號之前顯式聲明它們。相反,未聲明的符號只是未定義的,因此具有值 false。
條件編譯符號的命名空間與 C# 程序中的所有其他命名實體截然不同。只能在 #define 和 #undef 指令以及預處理表達式中引用條件編譯符號。
1

7. 什麼是預編譯,何時需要預編譯

預編譯又稱為預處理,是做些代碼文本的替換工作

預編譯又稱為預處理,是做些代碼文本的替換工作

處理#開頭的指令,比如拷貝#include包含的文件代碼,#define宏定義的替換,條件編譯等

就是為編譯做的預備工作的階段

主要處理#開始的預編譯指令

預編譯指令指示了在程序正式編譯前就由編譯器進行的操作,可以放在程序中的任何位置。常見的預編譯指令有:

(1)#include 指令

該指令指示編譯器將xxx.xxx文件的全部內容插入此處。若用<>括起文件則在系統的INCLUDE目錄中尋找文件,若用" "括起文件則在當前目錄中尋找文件。一般來說,該文件是後綴名為"h"或"cpp"的頭文件。

注意:<>不會在當前目錄下搜索頭文件,如果我們不用<>而用""把頭文件名擴起,其意義為在先在當前目錄下搜索頭文件,再在系統默認目錄下搜索。

(2)#define指令

該指令有三種用法:

第一種是定義標識,標識有效范圍為整個程序,形如#define XXX,常與#if配合使用;

第二種是定義常數,如#define max 100,則max代表100(這種情況下使用const定義常數更好,原因見注1);

第三種是定義"函數",如#define get_max(a, b) ((a)>(b)?(a):(b)) 則以後使用get_max(x,y)就可以得到x和y中較大的數(這種方法存在一些弊病,見注2)。

第四種是定義"宏函數",如#define GEN_FUN(type) type max_##type(type a,type b){return a>b?a:b;} ,使用時,用GEN_FUN(int),則此處預編譯後就變成了 max_int(int a,int b){return a>b?a:b;},以後就可以使用max_int(x,y)就可以得到x和y中較大的數.比第三種,增加了類型的說明。

(3)#if、#else和#endif指令

這些指令一般這樣配合使用:

#if defined(標識) //如果定義了標識

要執行的指令

#else

要執行的指令

#endif

在頭文件中為了避免重復調用(比如說兩個頭文件互相包含對方),常採用這樣的結構:

#if !(defined XXX) //XXX為一個在你的程序中唯一的標識符,

//每個頭文件的標識符都不應相同。

//起標識符的常見方法是若頭文件名為"abc.h"

//則標識為"abc_h"

#define XXX

真正的內容,如函數聲明之類

#endif

8. c++頭文件中的開頭代碼是啥意思

if
!defined
xxx
#define
xxxx
這是預編譯指令,是說,如果代碼中沒有定義xxx,則定義xxx,目的是,在引用文件時,防止重復定義
比如:在aaa.h中定義了AAA變數,
而在main.cpp
中#include
「AAA.h」,main.cpp也同時要使用fun.cpp.
並且在fun.cpp
中也#include「AAA.h」
那麼如果沒有預編譯指令的話
兩個文件都定義了AAA這個變數.那麼就造成了AAA的多次定義。
/*****************************/
/***文件一***main.cpp***********/
#include
"AAA.h"
int
main()
.....
/**文件二*****AAA.h************/
const
int
AAA
=
123;
/**文件三*****fun.cpp**************/
#include
"AAA.h"
.....
這樣,main文件包含了AAA變數的定義,由於main文件中會調用的fun.cpp,而fun.cpp文件包含了AAA.h也就是定義了AAA,
所以就會造成main文件定義了兩次AAA變數。
如果使用了預編譯指令,
則可以在定義了一次之後
不知道我說清楚了沒有,清楚了就請加分吧
不再定義第二次
由於

9. C語言含有包含自定義頭文件的程序怎麼編譯

1、只要在程序開頭加入#include
「自定義頭文件名」,在編譯過程當中,頭文件自動會被添加到源文件當中一起進行編譯。
2、編譯,編譯程序讀取源程序(字元流),對之進行詞法和語法的分析,將高級語言指令轉換為功能等效的匯編代碼,再由匯編程序轉換為機器語言,並且按照操作系統對可執行文件格式的要求鏈接生成可執行程序。C源程序頭文件-->預編譯處理(cpp)-->編譯程序本身-->優化程序-->匯編程序-->鏈接程序-->可執行文件。

熱點內容
pythonwhile 發布:2024-05-01 00:04:25 瀏覽:729
c語言用中文寫代碼能編譯通過嗎 發布:2024-04-30 23:59:18 瀏覽:535
小X分身存儲隔離 發布:2024-04-30 23:54:50 瀏覽:757
安卓電話錄音怎麼使用 發布:2024-04-30 23:42:38 瀏覽:413
windows運行python 發布:2024-04-30 23:38:18 瀏覽:783
節奏大師安卓腳本 發布:2024-04-30 23:25:18 瀏覽:421
ftp上傳進度 發布:2024-04-30 23:11:23 瀏覽:882
python網頁抓取 發布:2024-04-30 23:11:02 瀏覽:885
虛擬機linux無線 發布:2024-04-30 22:53:49 瀏覽:750
忘了信用卡密碼怎麼辦 發布:2024-04-30 22:47:43 瀏覽:722