當前位置:首頁 » 編程軟體 » 預編譯簡化

預編譯簡化

發布時間: 2022-05-21 09:46:06

⑴ 誰給簡單介紹一下C#

特點有很多,簡單易上手是比較明顯的
編程方式。。。你指什麼?
主要應用:網路,WEB開發
簡單,但是依然有它需要長時間研究的地方
IDE:VS系列,2003,2005,2008等
可以游戲開發,理論上是都能做的

⑵ C++中怎樣寫宏定義

C/C++中宏使用總結
.C/C++中宏總結C程序的源代碼中可包括各種編譯指令,這些指令稱為預處理命令。雖然它們實際上不是c語言的一部分,但卻擴展了C程
序設計的環境。本節將介紹如何應用預處理程序和注釋簡化程序開發過程,並提高程序的可讀性。

ANSI標準定義的C語言預處理程序包括下列命令:

#define,#error,#i
nclude,#if,#else,#elif,#endif,#ifdef,#ifndef,#undef,#line,#pragma等。非常明顯,所有預處理命令均以符號#開頭,下面分別加以介紹。

1、#define

命令#define定義了一個標識符及一個串。在源程序中每次遇到該標識符時,均以定義的串代換它。ANSI標准將標識符定義為宏名,將替換過程稱為宏
替換。命令的一般形式為:

#define identifier string

注意:

? 該語句沒有分號。在標識符和串之間可以有任意個空格,串一旦開始,僅由一新行結束。

? 宏名定義後,即可成為其它宏名定義中的一部分。

? 宏替換僅僅是以文本串代替宏標識符,前提是宏標識符必須獨立的識別出來,否則不進行替換。例如: #define XYZ
this is a test,使用宏printf("XYZ");//該段不列印"this is a test"而列印"XYZ"。因為預編譯器識
別出的是"XYZ"

? 如果串長於一行,可以在該行末尾用一反斜杠' \'續行。

2、#error

處理器命令#error強迫編譯程序停止編譯,主要用於程序調試。

3、#i nclude

命令#i nclude使編譯程序將另一源文件嵌入帶有#i nclude的源文件,被讀入的源文件必須用雙引號或尖括弧括起來。例如:

#i nclude"stdio.h"或者#i nclude

這兩行代碼均使用C編譯程序讀入並編譯用於處理磁碟文件庫的子程序。

將文件嵌入#i nclude命令中的文件內是可行的,這種方式稱為嵌套的嵌入文件,嵌套層次依賴於具體實現。

如果顯式路徑名為文件標識符的一部分,則僅在哪些子目錄中搜索被嵌入文件。否則,如果文件名用雙引號括起來,則首先檢索當前工作目錄。如果未發現文件,
則在命令行中說明的所有目錄中搜索。如果仍未發現文件,則搜索實現時定義的標准目錄。

如果沒有顯式路徑名且文件名被尖括弧括起來,則首先在編譯命令行中的目錄內檢索。

如果文件沒找到,則檢索標准目錄,不檢索當前工作目錄。

4、條件編譯命令

有幾個命令可對程序源代碼的各部分有選擇地進行編譯,該過程稱為條件編譯。商業軟體公司廣泛應用條件編譯來提供和維護某一程序的許多顧客版本。

#if、#else,#elif及#endif

#if的一般含義是如果#if後面的常量表達式為true,則編譯它與#endif之間的代碼,否則跳過這些代碼。命令#endif標識一個#if塊的
結束。

#if constant-expression

statement sequence

#endif

跟在#if後面的表達式在編譯時求值,因此它必須僅含常量及已定義過的標識符,不可使用變數。表達式不許含有操作符sizeof(sizeof也是編譯
時求值)。

#else命令的功能有點象C語言中的else;#else建立另一選擇(在#if失敗的情況下)。

注意,# else屬於# if塊。

#elif命令意義與ELSE IF 相同,它形成一個if else-if階梯狀語句,可進行多種編譯選擇。

#elif 後跟一個常量表達式。如果表達式為true,則編譯其後的代碼塊,不對其它#elif表達式進行測試。否則,順序測試下一塊。

#if expression

statement sequence

#elif expression1

statement sequence

#endif

在嵌套的條件編譯中#endif、#else或#elif與最近#if或#elif匹配。

# ifdef 和# ifndef

條件編譯的另一種方法是用#ifdef與#ifndef命令,它們分別表示"如果有定義"及"如果無定義"。

# ifdef的一般形式是:

# ifdef macroname

statement sequence

#endif

#ifdef與#ifndef可以用於#if、#else,#elif語句中,但必須與一個#endif。

5、#undef

命令#undef 取消其後那個前面已定義過有宏名定義。一般形式為:

#undef macroname

6、#line

命令# line改變__LINE__與__FILE__的內容,它們是在編譯程序中預先定義的標識符。命令的基本形式如下:

# line number["filename"]

其中的數字為任何正整數,可選的文件名為任意有效文件標識符。行號為源程序中當前行號,文件名為源文件的名字。命令# line主要用於調試及其它特殊
應用。

注意:在#line後面的數字標識從下一行開始的數字標識。

7、預定義的宏名

ANSI標准說明了C中的五個預定義的宏名。它們是:

__LINE__

__FILE__

__DATE__

__TIME__

__STDC__

如果編譯不是標準的,則可能僅支持以上宏名中的幾個,或根本不支持。記住編譯程序也許還提供其它預定義的宏名。

__LINE__及__FILE__宏指令在有關# line的部分中已討論,這里討論其餘的宏名。

__DATE__宏指令含有形式為月/日/年的串,表示源文件被翻譯到代碼時的日期。

源代碼翻譯到目標代碼的時間作為串包含在__TIME__中。串形式為時:分:秒。

如果實現是標準的,則宏__STDC__含有十進制常量1。如果它含有任何其它數,則實現是非標準的。編譯C++程序時,編譯器自動定義了一個預處理名
字__cplusplus,而編譯標准C時,自動定義名字__STDC__。

注意:宏名的書寫由標識符與兩邊各二條下劃線構成。

(部分內容出自:http://www.bc-cn.net/Article/kfyy/cyy/jc/200511/919.html)

8、C、C++宏體中出現的#,#@,##

宏體中,#的功能是將其後面的宏參數進行字元串化操作(Stringfication),簡單說就是在對它所引用的宏變數通過替換後在其左右各加上一個
雙引號。

而##被稱為連接符(concatenator),用來將兩個Token連接為一個Token。注意這里連接的對象是Token就行,而不一定是宏的變
量。比如你要做一個菜單項命令名和函數指針組成的結構體的數組,並且希望在函數名和菜單項命令名之間有直觀的、名字上的關系。那就可以使用:宏參數##
固定部分。當然還可以n個##符號連接 n+1個Token,這個特性也是#符號所不具備的。

#@的功能是將其後面的宏參數進行字元化。

9、C宏中的變參...

...在C宏中稱為Variadic Macro,也就是變參宏。比如:

#define myprintf(templt,...) fprintf(stderr,templt,__VA_ARGS__)

或者#define myprintf(templt,args...) fprintf(stderr,templt,args)

第一個宏中由於沒有對變參起名,我們用默認的宏__VA_ARGS__來替代它。第二個宏中,我們顯式地命名變參為args,那麼我們在宏定義中就可以
用args來代指變參了。同C語言的stdcall一樣,變參必須作為參數表的最後有一項出現。當上面的宏中我們只能提供第一個參數templt時,C
標准要求我們必須寫成: myprintf(templt,);的形式。這時的替換過程為:myprintf("Error!\n",);替換為:
fprintf(stderr,"Error!\n",).

這是一個語法錯誤,不能正常編譯。這個問題一般有兩個解決方法。首先,GNU CPP提供的解決方法允許上面的宏調用寫成:
myprintf(templt);而它將會被通過替換變成: fprintf(stderr,"Error!\n",);

很明顯,這里仍然會產生編譯錯誤(非本例的某些情況下不會產生編譯錯誤)。除了這種方式外,c99和GNU CPP都支持下面的宏定義方式:

#define myprintf(templt, ...) fprintf(stderr,templt, ##__VAR_ARGS__)

這時,##這個連接符號充當的作用就是當__VAR_ARGS__為空的時候,消除前面的那個逗號。那麼此時的翻譯過程如下:
myprintf(templt);被轉化為: fprintf(stderr,templt);

這樣如果templt合法,將不會產生編譯錯誤。

10、#pragma的使用【轉載】

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

其格式一般為: #Pragma Para,其中Para 為參數,下面來看一些常用的參數。

(1)message 參數。 Message 參數是我最喜歡的一個參數,它能夠在編譯信息輸出窗口中輸出相應的信息,這對於源代碼信息的控制是非常
重要的。其使用方法為:

#Pragma message("消息文本")

當編譯器遇到這條指令時就在編譯輸出窗口中將消息文本列印出來。

當我們在程序中定義了許多宏來控制源代碼版本的時候,我們自己有可能都會忘記有沒有正確的設置這些宏,此時我們可以用這條指令在編譯的時候就進行檢查。
假設我們希望判斷自己有沒有在源代碼的什麼地方定義了_X86這個宏可以用下面的方法

#ifdef _X86

#Pragma message("_X86 macro activated!")

#endif

當我們定義了_X86這個宏以後,應用程序在編譯時就會在編譯輸出窗口裡顯示"_

X86 macro activated!"。我們就不會因為不記得自己定義的一些特定的宏而抓耳撓腮了。

(2)另一個使用得比較多的pragma參數是code_seg。格式如:

#pragma code_seg( ["section-name"[,"section-class"] ] )

它能夠設置程序中函數代碼存放的代碼段,當我們開發驅動程序的時候就會使用到它。

(3)#pragma once (比較常用)

只要在頭文件的最開始加入這條指令就能夠保證頭文件被編譯一次,這條指令實際上在VC6中就已經有了,但是考慮到兼容性並沒有太多的使用它。

(4)#pragma hdrstop表示預編譯頭文件到此為止,後面的頭文件不進行預編譯。BCB可以預編譯頭文件以加快鏈接的速度,但如果所有頭文
件都進行預編譯又可能占太多磁碟空間,所以使用這個選項排除一些頭文件。

有時單元之間有依賴關系,比如單元A依賴單元B,所以單元B要先於單元A編譯。你可以用#pragma startup指定編譯優先順序,如果使用了
#pragma package(smart_init) ,BCB就會根據優先順序的大小先後編譯。

(5)#pragma resource "*.dfm"表示把*.dfm文件中的資源加入工程。*.dfm中包括窗體、外觀的定義。

(6)#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 也支持如下格式:

#pragma warning( push [ ,n ] )

#pragma warning( pop )

這里n代表一個警告等級(1---4)。

#pragma warning( push )保存所有警告信息的現有的警告狀態。

#pragma warning( push, n)保存所有警告信息的現有的警告狀態,並且把全局警告等級設定為n。

#pragma warning( pop )向棧中彈出最後一個警告信息,在入棧和出棧之間所作的一切改動取消。例如:

#pragma warning( push )

#pragma warning( disable : 4705 )

#pragma warning( disable : 4706 )

#pragma warning( disable : 4707 )

//.......

#pragma warning( pop )

在這段代碼的最後,重新保存所有的警告信息(包括4705,4706和4707)。
(7)pragma comment(...)

該指令將一個注釋記錄放入一個對象文件或可執行文件中。

常用的lib關鍵字,可以幫我們連入一個庫文件。

(8)用pragma導出dll中的函數

傳統的到出 DLL 函數的方法是使用模塊定義文件 (.def),Visual C++ 提供了更簡潔方便的方法,那就
是"__declspec()"關鍵字後面跟"dllexport",告訴連接去要導出這個函數,例如:

__declspec(dllexport) int __stdcall MyExportFunction(int iTest);

把"__declspec(dllexport)"放在函數聲明的最前面,連接生成的 DLL 就會導出函
數"_MyExportFunction@4"。

上面的導出函數的名稱也許不是我的希望的,我們希望導出的是原版的"MyExportFunction"。還好,VC 提供了一個預處理指示
符"#pragma"來指定連接選項 (不僅僅是這一個功能,還有很多指示功能) ,如下:

#pragma comment(linker,"/EXPORT:MyExportFunction=_MyExportFunction@4")

這下就天如人願了:)。如果你想指定導出的順序,或者只將函數導出為序號,沒有 Entryname,這個預處理指示符 (確切地說是連接器) 都能夠
實現,看看 MSDN 的語法說明:

/EXPORT:entryname[,@ordinal[,NONAME]][,DATA]

@ordinal 指定順序;NONAME 指定只將函數導出為序號;DATA 關鍵字指定導出項為數據項。

⑨每個編譯程序可以用#pragma指令激活或終止該編譯程序支持的一些編譯功能。例如,對循環優化功能:

#pragma loop_opt(on) // 激活

#pragma loop_opt(off) // 終止

有時,程序中會有些函數會使編譯器發出你熟知而想忽略的警告,如"Parameter xxx is never used in function
xxx",可以這樣:

#pragma warn -100 // Turn off the warning message for warning #100

int insert_record(REC *r)

{ /* function body */ }

#pragma warn +100 // Turn the warning message for warning #100 back
on

函數會產生一條有唯一特徵碼100的警告信息,如此可暫時終止該警告。

每個編譯器對#pragma的實現不同,在一個編譯器中有效在別的編譯器中幾乎無效。可從編譯器的文檔中查看。
⑩#pragm pack()的使用

#pragma pack規定的對齊長度,實際使用的規則是:

? 結構,聯合,或者類的數據成員,第一個放在偏移為0的地方,以後每個數據成員的對齊,按照#pragma pack指定的數值和這
個數據成員自身長度中,比較小的那個進行。

? 也就是說,當#pragma pack的值等於或超過所有數據成員長度的時候,這個值的大小將不產生任何效果。

? 而結構整體的對齊,則按照結構體中最大的數據成員 和 #pragma pack指定值之間,較小的那個進行。

注意:文件使用#pragma pack(n) 改變了預設設置而不恢復,通常可以使用#pragma pack(push, n)和#pragma
pack(pop)進行設置與恢復。

註:關於宏函數的內容在另外的專題。關於宏使用的誤區在描述宏的時候已經在文中提到了,最後再給出一個例子,描述的Side Effect是指宏在展開
的時候對其參數可能進行多次Evaluation(也就是取值)對程序造成的錯誤影響。

假設在一個系統中,有一個32b的寄存器(REG)保存狀態,其中高16b表示一種含義,低16b表示另一種含義(這在程序中經常出現)。現在要把高低
16b分開,不考慮實際中的特殊要求,將代碼寫成:

#define High16bit(REG) (REG>>16)

#define Low16bit(REG) ((REG<<16)>>16)

對於這種寫法完成的功能在大多數情況是足夠了,這里不討論。主要談論這種寫法的負面影響,如果在程序中分別在不同的語句中使用High16bit和
Low16bit,那麼就可能那就是Side effect,特別寄存器REG是狀態寄存器,他的狀態可能隨時變化,那麼引起的問題就是高低16b根本
取的不是同一個時刻狀態寄存器。這種錯誤在程序中找出就比較難了。在這里我把條件弱化了,試想在一個宏體中,如果對參數多次取值也是可能引起問題,那就 更難了。

⑶ 在ibatis及mybatis的sqlmap配置文件中應使用什麼符號進行安全預編譯參數綁定

這個區別不是很大,最主要的區別就是mybatis簡化了編碼的過程,不需要去寫的實現類,直接寫一個的介面,再寫一個xml配置文件,整個mybatis就配置好了,也就是資料庫就連接好了,然後在service裡面直接調用就可以了,但是ibatis則不可以

⑷ 預處理是什麼 包括哪兩種方法

資料庫基礎分析為什麼要進行預處理數據 收藏
做數據預處理很重要,但是如何做好數據預處理似乎是件更困難的事。。。。。

-----------------------------------------------------------------------------------------------------------------------

當今現實世界的資料庫極易受雜訊、丟失數據和不一致數據的侵擾,因為資料庫太大(常常多達數千兆位元組,甚至更多),並且多半來自多個異構數據源。低質量的數據將導致低質量的挖掘結果。「如何預處理數據提高數據質量,從而提高挖掘結果的質量?如何預處理數據,使得挖掘過程更加有效、更加容易?」

有大量數據預處理技術。數據清理可以用來去掉數據中的雜訊,糾正不一致。數據集成將數據由多個源合並成一致的數據存儲,如數據倉庫。也可以使用數據變換,如規范化。例如,規范化可以提高涉及距離度量的挖掘演算法的准確率和有效性。數據歸約可以通過聚集、刪除冗餘特徵或聚類等方法來減小數據規模。這些技術不是互斥的,可以一起使用。例如,數據清理可能涉及糾正錯誤數據的變換,如將日期欄位變換成共同的格式。這些數據處理技術在挖掘之前使用,可以顯著地提高挖掘模式的總體質量和/或減少實際挖掘所需要的時間。

介紹數據預處理的基本概念,介紹作為數據預處理基礎的描述性數據匯總。描述性數據匯總幫助我們研究數據的一般特徵、識別雜訊或離群點,對成功的數據清理和數據集成很有用。數據預處理的方法組織如下:數據清理、數據集成與變換和數據歸約。概念分層可以用作數據歸約的一種替換形式,其中低層數據(如年齡的原始值)用高層概念(如青年、中年或老年)替換。這種形式的數據歸約,在那裡我們討論使用數據離散化技術,由數值數據自動地產生概念分層。

為什麼要預處理數據

想像你是AllElectronics的經理,負責分析涉及你部門的公司銷售數據。你立即著手進行這項工作,仔細地審查公司的資料庫和數據倉庫,識別並選擇應當包含在分析中的屬性或維,如item, price和units_sold。啊!你注意到許多元組在一些屬性上沒有值。為了進行分析,希望知道每種購進的商品是否作了銷售廣告,但是發現這些信息沒有記錄下來。此外,你的資料庫系統用戶已經報告某些事務記錄中的一些錯誤、不尋常的值和不一致性。換言之,你希望

使用數據挖掘技術分析的數據是不完整的(缺少屬性值或某些感興趣的屬性,或僅包含聚集數據),含雜訊的(包含錯誤或存在偏離期望的離群值),並且是不一致的(例如,用於商品分類的部門編碼存在差異)。歡迎來到現實世界!

存在不完整的、含雜訊的和不一致的數據是現實世界大型的資料庫或數據倉庫的共同特點。不完整數據的出現可能有多種原因。有些感興趣的屬性,如銷售事務數據中顧客的信息,並非總是可用的。其他數據沒有包含在內只是因為輸入時認為是不重要的。相關數據沒有記錄可能是由於理解錯誤,或者因為設備故障。與其他記錄不一致的數據可能已經刪除。此外,記錄歷史或修改的數據可能被忽略。缺失的數據,特別是某些屬性上缺少值的元組可能需要推導出來。

數據含雜訊(具有不正確的屬性值)可能有多種原因。收集數據的設備可能出故障;人或計算機的錯誤可能在數據輸入時出現;數據傳輸中的錯誤也可能出現。這些可能是由於技術的限制,如用於數據傳輸同步的緩沖區大小的限制。不正確的數據也可能是由命名約定或所用的數據代碼不一致,或輸入欄位(如日期)的格式不一致而導致的。重復元組也需要數據清理。

數據清理常式通過填寫缺失的值、光滑雜訊數據、識別或刪除離群點並解決不一致性來「清理」數據。如果用戶認為數據是臟的,則他們不會相信這些數據的挖掘結果。此外,臟數據造成挖掘過程陷入混亂,導致不可靠的輸出。盡管大部分挖掘常式都有一些過程處理不完整或雜訊數據,但它們並非總是魯棒的。相反,它們著重於避免建模函數過分擬合數據。因此,一個有用的預處理步驟是使用一些清理常式處理數據。2.3節討論清理數據的方法。回到你在AllElectronics的任務,假定在分析中包含來自多個數據源的數據。這涉及集成48 多個資料庫、數據立方體或文件,即數據集成。代表同一概念的屬性在不同的資料庫中可能有不同的名字,這將導致不一致性和冗餘。例如,顧客標識屬性在一個資料庫中可能是customer_id,而在另一個中為cust_id。命名的不一致還可能出現在屬性值中。例如,同一個人的名字可能在一個資料庫中登記為「Bill」,在第二個資料庫中登記為「William」,而在第三個資料庫中登記為「B」。此外,你可能會覺察到,有些屬性可能是由其他屬性(例如年收入)導出的。含大量冗餘數據可能降低知識發現過程的性能或使之陷入混亂。顯然,除數據清理之外,在數據集成時必須採取步驟,避免數據冗餘。通常,在為數據倉庫准備數據時,數據清理和集成將作為預處理步驟進行。還可以再次進行數據清理,檢測和刪去可能由集成導致的冗餘。

回到你的數據,假設你決定要使用諸如神經網路、最近鄰分類法或聚類這樣的基於距離的挖掘演算法進行分析。如果待分析的數據已經規范化,即按比例映射到一個特定的區間[0.0,1.0],這些方法能得到更好的結果。例如,你的顧客數據包含年齡和年薪屬性。年薪屬性的取值范圍可能比年齡大得多。這樣,如果屬性未規范化,距離度量對年薪所取的權重一般要超過距離度量對年齡所取的權重。此外,分析得到每個客戶區域的銷售額這樣的聚集信息可能是有用的。這種信息不在你的數據倉庫的任何預計算的數據立方體中。你很快意識到,數據變換操作,如規范化和聚集,是導向挖掘過程成功的預處理過程。

隨著你進一步考慮數據,你想知道「我選擇用於分析的數據集太大了,肯定降低挖掘過程的速度。有沒有辦法壓縮我的數據集而又不損害數據挖掘的結果?」數據歸約得到數據集的簡化表示,它小得多,但能夠產生同樣的(或幾乎同樣的)分析結果。有許多數據歸約策略,包括數據聚集(例如建立數據立方體)、屬性子集選擇(例如通過相關分析去掉不相關的屬性)、維度歸約(例如使用諸如最小長度編碼或小波等編碼方案)和數值歸約(例如使用聚類或參數模型等較小的表示「替換」數據)。使用概念分層泛化也可以「歸約」數據。泛化用較高層的概念替換較低層的概念,例如,對於顧客位置,用region或49 province_or_state替換city。概念分層將概念組織在不同的抽象層。數據離散化是一種數據歸約形式,對於從數值數據自動地產生概念分層是非常有用的。

下圖總結了這里討論的數據預處理步驟。注意,上面的分類不是互斥的。例如,冗餘數據的刪除既是一種數據清理形式,也是一種數據歸約。

概言之,現實世界的數據一般是臟的、不完整的和不一致的。數據預處理技術可以改進神經網路和最近鄰分類法在第6章介紹,聚類在第7章討論。

數據的質量,從而有助於提高其後的挖掘過程的精度和性能。由於高質量的決策必然依賴於高質量的數據,因此數據預處理是知識發現過程的重要步驟。檢測數據異常、盡早地調整數據並歸約待分析的數據,將在決策過程得到高回報。

⑸ C語言中%c表示什麼意思

「%」在c語言中有兩種釋義,一是求余符號,經常會用到判斷一個數是不是能被另一個整除;二是引導符,用於引導輸入輸出項表列的格式,C語言運算符號的種類編輯:

1、算術運算符

用於各類數值運算。包括加(+)、減(-)、乘(*)、除(/)、求余(或稱模運算,%)、自增(++)、自減(--)共七種。

2、關系運算符

用於比較運算。包括大於(>)、小於(<)、等於(==)、 大於等於(>=)、小於等於(<=)和不等於(!=)六種。

3、邏輯運算符

用於邏輯運算。包括與(&&)、或(||)、非(!)三種。

(5)預編譯簡化擴展閱讀:

c語言特有特點

C語言是一個有結構化程序設計、具有變數作用域(variable scope)以及遞歸功能的過程式語言。

C語言傳遞參數均是以值傳遞(pass by value),另外也可以傳遞指針(a pointer passed by value)。不同的變數類型可以用結構體(struct)組合在一起。通過指針(pointer),C語言可以容易的對存儲器進行低級控制。預編譯處理(preprocessor)讓C語言的編譯更具有彈性。

⑹ 程序的編譯期,鏈接期, 運行期各執行哪些操作

參考一下:

源文件的編譯過程包含兩個主要階段,而它們之間的轉換是自動的。第一個階段是預處理階段,在正式的編譯階段之前進行。預處理階段將根據已放置在文件中的預處理指令來修改源文件的內容。#include指令就是一個預處理指令,它把頭文件的內容添加到.cpp文件中還有其他許多預處理指令
這個在編譯之前修改源文件的方式提供了很大的靈活性,以適應不同的計算機和操作系統環境的限制。一個環境需要的代碼跟另一個環境所需的代碼可能有所不同,因為可用的硬體或操作系統是不同的。在許多情況下,可以把用於不同環境的代碼放在同一個文件中,再在預處理階段修改代碼,使之適應當前的環境。
預處理器顯示為一個獨立的操作,但一般不能獨立於編譯器來執行這個操作。調用編譯器會自動執行預處理過程,之後才編譯代碼。
編譯器為給定源文件輸出的是機器碼,執行這個過程需要較長時間。在對象文件之間並沒有建立任何連接。對應於某個源文件的對象文件包含在其他源文件中定義的函數引用或其他指定項的引用,而這些函數或項仍沒有被解析。同樣,也沒有建立同庫函數的鏈接。實際上,這些函數的代碼並不是文件的一部分。這些工作是由鏈接程序(有時稱為鏈接編輯器)完成的
鏈接程序把所有對象文件中的機器碼組合在一起,並解析它們之間的交叉引用。它還集成了對象模塊所使用的庫函數的代碼。這是鏈接程序的一種簡化表示,因為這里假定在可執行模塊中,模塊之間的所有鏈接都是靜態建立的。實際上有些鏈接是動態的,即這些鏈接是在程序執行時建立的。

鏈接程序靜態地建立函數之間的鏈接,即在程序執行之前建立組成程序的源文件中所包含的函數鏈接。動態建立的函數之間的鏈接(在程序執行過程中建立的鏈接)將函數編譯並鏈接起來,創建另一種可執行模塊—— 動態鏈接庫或共享庫。動態鏈接庫中的函數鏈接是在程序調用函數時才建立的,在程序調用之前,該鏈接是不存在的。

動態鏈接庫有幾個重要的優點。一個主要的優點是動態鏈接庫中的函數可以在幾個並行執行的程序之間共享,這將節省相同函數佔用的內存空間。另一個優點是動態鏈接庫在調用其中的函數之前是不會載入到內存中的。也就是說,如果不使用給定動態鏈接庫中的函數,該動態鏈接庫就不會佔用內存空間

⑺ (ElemType *)是啥意思

ElemType(也有的書上稱之為elemtp)是數據結構的書上為了說明問題而用的一個詞。它是element type(「元素的類型」)的簡化體。

因為數據結構是討論抽象的數據存儲和演算法的,一種結構中元素的類型不一定是整型、字元型、浮點型或者用戶自定義類型,為了不重復說明,使用過程中用「elemtype」代表所有可能的數據類型,簡單明了的概括了整體。

例子:ElemType *是定義指向這種類型的指針,p=(ElemType *)malloc(8*sizeof(ElemType)),開辟8個ElemType大小的內存空間,把地址分配給指向ElemType的指針p。

(7)預編譯簡化擴展閱讀:

elem是單詞element(元素)的縮寫,在程序定義中代表某一不確定的類型,也就是抽象的數據類型。

為了使程序可讀性強,並且便於修改,讓elem代表多種的數據類型,也就是為int、char等等的數據類型,起了一個別名。

在頭文件中定義:typedef char elem; 表示:抽象元素類型為char類型,這樣定義之後,下面的程序中elem所定義的元素就是char類型的了。

如果需要修改其類型,直接修改char到其他類型,elem便又代表了所修改的類型數據,這也是方便性的體現。

(ElemType *)具體用法是:

template <typename elemtype> typedef struct{ elemtype *elem;

int length;int listsize; }sqlist;

之後聲明變數時要賦予elemtype一個已知的類型,比如int。 struct sqlist<int> a; 對於a這裡面的elemtype就變成了int。 不過這是C++的內容,C裡面不能用。

如果不用模板,而必須在C語言里用的話,有兩種方法:

1、之前聲明它 typedef int elemtype;

2、之前預編譯它 #define elemtype int

參考資料:網路:elem type

⑻ CSS 的預處理程序分別都有哪些優缺點

普遍的三款 CSS 預處理器框架,分別是 Sass、Less CSS、Stylus。

  1. CSS 預處理器概述:CSS 預處理器是一種語言用來為 CSS 增加一些編程的的特性,無需考慮瀏覽器的兼容性問題,例如你可以在 CSS 中使用變數、簡單的程序邏輯、函數等等在編程語言中的一些基本技巧,可以讓你的 CSS 更見簡潔,適應性更強,代碼更直觀等諸多好處。

    總結來講就是用編程的方法來寫CSS樣式,而不是手工一行行碼,相當於從手工業時代進化到工業時代。

  2. 三種CSS 預處理器(框架)簡介:

    A、SASS2007年誕生,最早也是最成熟的CSS預處理器,擁有ruby社區的支持和compass這一最強大的css框架,目前受LESS影響,已經進化到了全面兼容CSS的SCSS。

    B、LESS2009年出現,受SASS的影響較大,但又使用CSS的語法,讓大部分開發者和設計師更容易上手,在ruby社區之外支持者遠超過SASS,其缺點是比起SASS來,可編程功能不夠,不過優點是簡單和兼容CSS,反過來也影響了SASS演變到了SCSS的時代,著名的Twitter Bootstrap就是採用LESS做底層語言的。

    C、Stylus,2010年產生,來自Node.js社區,主要用來給Node項目進行CSS預處理支持,在此社區之內有一定支持者,在廣泛的意義上人氣還完全不如SASS和LESS。

  3. Stylus主要優點:
    1. 簡短直觀,縮進讓CSS的層次非常直觀。
    2. At 屬性引用可以減少維護量。
    3. 函數和Mixin,重用的利器。

  4. CSS 預處理器優缺點:

    A、可以把PostCSS和預處理器(Sass、Stylus或LESS)結合起來使用。

    B、部分PostCSS插件配合預處理器將功能添加到你的工作流中,讓你工作變得更加輕松。如果只使用一個預處理器,而不使用這些插件,工作流至少會變得更加困難。

    C、PostCSS插件和喜歡的預處理器(Sass、Stylus或LESS)之一結合在一起使用。

    D、在常規的預處理器通過使用混合宏或函數特性像程序一樣處理代碼,達到類似的結果。不過不同的是CSS代碼,而其他一切通過插件去處理,而這個過程中不需要調用函數,也沒有混合宏等等。

  5. 使用技巧:Sass看起來在提供的特性上佔有優勢,但是LESS能夠讓開發者平滑地從現存CSS文件過渡到LESS,而不需要像Sass那樣需要將CSS文件轉換成Sass格式。

⑼ 關於C語言預處理命令

C程序的源代碼中可包括各種編譯指令,這些指令稱為預處理命令。雖然它們實際上不是C語言的一部分,但卻擴展了C程序設計的環境。本節將介紹如何應用預處理程序和注釋簡化程序開發過程,並提高程序的可讀性。ANSI標準定義的C語言預處理程序包括下列命令:
#define,#error,#include,#if,#else,#elif,#endif,#ifdef,#ifndef,#undef,#line,#pragma等。非常明顯,所有預處理命令均以符號#開頭,下面分別加以介紹。

一 #define
命令#define定義了一個標識符及一個串。在源程序中每次遇到該標識符時,均以定義的串代換它。ANSI標准將標識符定義為宏名,將替換過程稱為宏替換。命令的一般形式為:
#define identifier string
注意:
1該語句沒有分號。在標識符和串之間可以有任意個空格,串一旦開始,僅由一新行結束。
2宏名定義後,即可成為其它宏名定義中的一部分。
3 宏替換僅僅是以文本串代替宏標識符,前提是宏標識符必須獨立的識別出來,否則不進行替換。例如:
#define XYZ this is a tes
使用宏printf("XYZ");//該段不列印"this is a test"而列印"XYZ"。因為預編譯器識別出的是"XYZ"
4如果串長於一行,可以在該行末尾用一反斜杠' \'續行。
#defineLONG_STRING"this is a very long\
string that is used as an example"
5 C語言程序普遍使用大寫字母定義標識符。
6 用宏代換代替實在的函數的一大好處是宏替換增加了代碼的速度,因為不存在函數調用的開銷。但增加速度也有代價:由於重復編碼而增加了程序長度。

二 #error
命令#error強迫編譯程序停止編譯,主要用於程序調試。
#error指令使預處理器發出一條錯誤消息,該消息包含指令中的文本.這條指令的目的就是在程序崩潰之前能夠給出一定的信息。
三 #include
命令#i nclude使編譯程序將另一源文件嵌入帶有#include的源文件,被讀入的源文件必須用雙引號或尖括弧括起來。例如:
#include"stdio.h"或者#include<stdio.h>
這兩行代碼均使用C編譯程序讀入並編譯用於處理磁碟文件庫的子程序。
將文件嵌入#i nclude命令中的文件內是可行的,這種方式稱為嵌套的嵌入文件,嵌套層次依賴於具體實現。
如果顯式路徑名為文件標識符的一部分,則僅在那些子目錄中搜索被嵌入文件。否則,如果文件名用雙引號括起來,則首先檢索當前工作目錄。如果未發現文件,則在命令行中說明的所有目錄中搜索。如果仍未發現文件,則搜索實現時定義的標准目錄。
如果沒有顯式路徑名且文件名被尖括弧括起來,則首先在編譯命令行中的目錄內檢索。如果文件沒找到,則檢索標准目錄,不檢索當前工作目錄。
四 條件編譯命令
有幾個命令可對程序源代碼的各部分有選擇地進行編譯,該過程稱為條件編譯。商業軟體公司廣泛應用條件編譯來提供和維護某一程序的許多顧客版本。
#if、#else,#elif及#endif
#if的一般含義是如果#if後面的常量表達式為true,則編譯它與#endif之間的代碼,否則跳過這些代碼。命令#endif標識一個#if塊的結束。
#if constant-expression
statement sequence
#endif
Eg:
#define MAX 91
#include <iostream>
using namespace std;
int main()
{
#if MAX > 99
cout<<"MAX is bigger than 99"<<endl;
#elif MAX > 90
cout<<"MAX is bigger than 90"<<endl;
#else
cout<<"MAX is smaller than 90"<<endl;
#endif
return 0;
}
跟在#if後面的表達式在編譯時求值,因此它必須僅含常量及已定義過的標識符,不可使用變數。表達式不許含有操作符sizeof(sizeof也是編譯時求值)。

#else命令的功能有點象C語言中的else;#else建立另一選擇(在#if失敗的情況下)。注意,#else屬於#if塊。

#elif命令意義與ELSE IF 相同,它形成一個if else-if階梯狀語句,可進行多種編譯選擇。#elif 後跟一個常量表達式。如果表達式為true,則編譯其後的代碼塊,不對其它#elif表達式進行測試。否則,順序測試下一塊。

#if expression
statement sequence
#elif expression1
statement sequence
#endif

在嵌套的條件編譯中#endif、#else或#elif與最近#if或#elif匹配。
# ifdef 和# ifndef

條件編譯的另一種方法是用#ifdef與#ifndef命令,它們分別表示"如果有定義"及"如果無定義"。# ifdef的一般形式是:

# ifdef macroname
statement sequence
#endif

#ifdef與#ifndef可以用於#if、#else,#elif語句中,但必須與一個#endif。

#define MAX 91
#include <iostream>
using namespace std;

int main()
{
#ifdef MAX
cout<<"hello,MAX!"<<endl;
#else
cout<<"where is MAX?"<<endl;
#endif
#ifndef LEO
cout<<"LEO is not defined"<<endl;
#endif
return 0;
}
命令#undef 取消其後那個前面已定義過有宏名定義。一般形式為:
#undef macroname
命令#line改變__LINE__與__FILE__的內容,它們是在編譯程序中預先定義的標識符。命令的基本形式如下:
#line number["filename"]
其中的數字為任何正整數,可選的文件名為任意有效文件標識符。行號為源程序中當前行號,文件名為源文件的名字。命令#line主要用於調試及其它特殊應用。注意:在#line後面的數字標識從下一行開始的數字標識。
#line 100 "jia"
cout<<"#line change line and filename!"<<endl; //line 100
cout<<__LINE__<<endl; //101
cout<<__FILE__<<endl; //jia
五 #pragma
命令#pragma 為實現時定義的命令,它允許向編譯程序傳送各種指令。
#pragma的作用是設定編譯器的狀態或者是指示編譯器完成一些特定的動作。#pragma指令對每個編譯器給出了一個方法,在保持與C和C++語言完全兼容的情況下,給出主機或操作系統專有的特徵。依據定義,編譯指示是機器或操作系統專有的,且對於每個編譯器都是不同的。
其格式一般為: #Pragma Para
1 message 參數。
Message 參數能夠在編譯信息輸出窗口中輸出相應的信息,這對於源代碼信息的控制是非常重要的。其使用方法為:
#pragma message(「消息文本」)
當編譯器遇到這條指令時就在編譯輸出窗口中將消息文本列印出來。
當在程序中定義了許多宏來控制源代碼版本的時候,自己有可能都會忘記有沒有正確的設置這些宏,此時可以用這條指令在編譯的時候就進行檢查。假設希望判斷自己有沒有在源代碼的什麼地方定義了_X86這個宏可以用下面的方法
#ifdef _X86
#pragma message(「_X86 macro activated!」)
#endif
當定義了_X86這個宏以後,應用程序在編譯時就會在編譯輸出窗口裡顯示「_
X86 macro activated!」。就不會因為不記得自己定義的一些特定的宏而抓耳撓腮了。

2 code_seg 參數。
格式如:
#pragma code_seg( ["section-name"[,"section-class"] ] )
它能夠設置程序中函數代碼存放的代碼段,當開發驅動程序的時候就會使用到它。

3 #pragma once (比較常用)
只要在頭文件的最開始加入這條指令就能夠保證頭文件被編譯一次。這條指令實際上在VC6中就已經有了,但是考慮到兼容性並沒有太多的使用它。

4 #pragma hdrstop
表示預編譯頭文件到此為止,後面的頭文件不進行預編譯。BCB可以預編譯頭文件以加快鏈接的速度,但如果所有頭文件都進行預編譯又可能占太多磁碟空間,所以使用這個選項排除一些頭文件。
有時單元之間有依賴關系,比如單元A依賴單元B,所以單元B要先於單元A編譯。你可以用#pragma startup指定編譯優先順序,如果使用了#pragma package(smart_init) ,BCB就會根據優先順序的大小先後編譯。

5 #pragma resource "*.dfm"
表示把*.dfm文件中的資源加入工程。*.dfm中包括窗體外觀的定義。

6 #pragma warning( disable : 4507 34; once : 4385; error : 164 )
等價於:
#pragma warning(disable:4507 34) /* 不顯示4507和34號警告信息。如果編譯時總是出現4507號警告和34號警告, 而認為肯定不會有錯誤,可以使用這條指令。*/
#pragma warning(once:4385) // 4385號警告信息僅報告一次
#pragma warning(error:164) // 把164號警告信息作為一個錯誤。
同時這個pragma warning 也支持如下格式:
#pragma warning( push [ ,n ] )
#pragma warning( pop )
這里n代表一個警告等級(1---4)。
#pragma warning( push )保存所有警告信息的現有的警告狀態。
#pragma warning( push, n)保存所有警告信息的現有的警告狀態,並且把全局警告等級設定為n。
#pragma warning( pop )向棧中彈出最後一個警告信息,在入棧和出棧之間所作的一切改動取消。例如:
#pragma warning( push )
#pragma warning( disable : 4705 )
#pragma warning( disable : 4706 )
#pragma warning( disable : 4707 )
//.......
#pragma warning( pop )
在這段代碼的最後,重新保存所有的警告信息(包括4705,4706和4707)。

7 pragma comment(...)
該指令將一個注釋記錄放入一個對象文件或可執行文件中。
常用的lib關鍵字,可以幫連入一個庫文件。

8 progma pack(n)
指定結構體對齊方式。#pragma pack(n)來設定變數以n位元組對齊方式。
n 位元組對齊就是說變數存放的起始地址的偏移量有兩種情況:
第一、如果n大於等於該變數所佔用的位元組數,那麼偏移量必須滿足默認的對齊方式,
第二、如果n小於該變數的類型所佔用的位元組數,那麼偏移量為n的倍數,不用滿足默認的對齊方式。
結構的總大小也有個約束條件,分下面兩種情況:如果n大於所有成員變數類型所佔用的位元組數,那麼結構的總大小必須為佔用空間最大的變數佔用的空間數的倍數; 否則必須為n的倍數。
下面舉例說明其用法。
#pragma pack(push) //保存對齊狀態
#pragma pack(4)//設定為4位元組對齊
struct test
{
char m1;
double m4;
int m3;
};
#pragma pack(pop)//恢復對齊狀態
為測試該功能,可以使用sizeof()測試結構體的長度!

⑽ 通過條件編譯使得 字元串轉換大小寫,可以通過程序中動態的判斷執行嗎。

/*
宏預處理解決不了你的問題,請參考如下程序:
*/

#include <stdio.h>

int main(int argc, char* argv[])
{
char str[20] = "C Language";
char c;
int i = 0;
int convert_type = 1; /*1表示轉大寫,2表示轉小寫. 默認轉大寫*/

if ( argc > 1 )
{
if ( strcmp(argv[1], "2") == 0 )
{
convert_type = 2; /*轉小寫*/
}
}

while((c=str[i])!='\0')
{
i++;
if ( convert_type == 1 )
{
if( c >= 'a' && c <= 'z' )
{
c = c - 32;
}
}
else
{
if( c >= 'A' && c <= 'Z' )
{
c = c + 32;
}
}

printf("%c", c);
}

return 0;
}

/*
使用示例:
假設exe文件名稱為test.exe,如下運行

轉大寫:
test.exe
test.exe 1
轉小寫:
test.exe 2
*/

熱點內容
java返回this 發布:2025-10-20 08:28:16 瀏覽:645
製作腳本網站 發布:2025-10-20 08:17:34 瀏覽:936
python中的init方法 發布:2025-10-20 08:17:33 瀏覽:632
圖案密碼什麼意思 發布:2025-10-20 08:16:56 瀏覽:821
怎麼清理微信視頻緩存 發布:2025-10-20 08:12:37 瀏覽:731
c語言編譯器怎麼看執行過程 發布:2025-10-20 08:00:32 瀏覽:1066
郵箱如何填寫發信伺服器 發布:2025-10-20 07:45:27 瀏覽:299
shell腳本入門案例 發布:2025-10-20 07:44:45 瀏覽:160
怎麼上傳照片瀏覽上傳 發布:2025-10-20 07:44:03 瀏覽:850
python股票數據獲取 發布:2025-10-20 07:39:44 瀏覽:763