預編譯標志符號
編譯,編譯程序讀取源程序(字元流),對之進行詞法和語法的分析,將高級語言指令轉換為功能等效的匯編代碼,再由匯編程序轉換為機器語言,並且按照操作系統對可執行文件格式的要求鏈接生成可執行程序。
如果用一張圖來表示:
讀取c源程序,對其中的偽指令(以#開頭的指令)和特殊符號進行處理
[析] 偽指令主要包括以下四個方面
(1)宏定義指令,如#define Name TokenString,#undef等。對於前一個偽指令,預編譯所要做的是將程序中的所有Name用TokenString替換,但作為字元串常量的Name則不被替換。對於後者,則將取消對某個宏的定義,使以後該串的'出現不再被替換。
(2)條件編譯指令,如#ifdef,#ifndef,#else,#elif,#endif,等等。這些偽指令的引入使得程序員可以通過定義不同的宏來決定編譯程序對哪些代碼進行處理。預編譯程序將根據有關的文件,將那些不必要的代碼過濾掉
(3)頭文件包含指令,如#include "FileName"或者#include 等。在頭文件中一般用偽指令#define定義了大量的宏(最常見的是字元常量),同時包含有各種外部符號的聲明。採用頭文件的目的主要是為了使某些定義可以供多個不同的C源程序使用。因為在需要用到這些定義的C源程序中,只需加上一條#include語句即可,而不必再在此文件中將這些定義重復一遍。預編譯程序將把頭文件中的定義統統都加入到它所產生的輸出文件中,以供編譯程序對之進行處理。
包含到c源程序中的頭文件可以是系統提供的,這些頭文件一般被放在/usr/include目錄下。在程序中#include它們要使用尖括弧(<>)。另外開發人員也可以定義自己的頭文件,這些文件一般與c源程序放在同一目錄下,此時在#include中要用雙引號("")。
(4)特殊符號,預編譯程序可以識別一些特殊的符號。例如在源程序中出現的LINE標識將被解釋為當前行號(十進制數),FILE則被解釋為當前被編譯的C源程序的名稱。預編譯程序對於在源程序中出現的這些串將用合適的值進行替換。
注意:
預編譯程序所完成的基本上是對源程序的「替代」工作。經過此種替代,生成一個沒有宏定義、沒有條件編譯指令、沒有特殊符號的輸出文件。這個文件的含義同沒有經過預處理的源文件是相同的,但內容有所不同。下一步,此輸出文件將作為編譯程序的輸出而被翻譯成為機器指令。
Ⅱ c++ 預編譯問題 關於頭文件
預編譯不能這么寫吧?你想達到的目的是不讓ElemType不重復定義?
這樣試試
#ifndef HEADER_ELEM_TYPE_H
#define HEADER_ELEM_TYPE_H
struct ElemType{
int number; //物品編號
int weight;
};
#endif
int main(){
ElemType a;
}
用這個宏HEADER_ELEM_TYPE_H來判斷當前文件是否被包含
如果你用vs2008的話應該可以用另外一個宏指令達到你上面的目的
#pragma once
struct ElemType{
int number; //物品編號
int weight;
};
這樣多簡單
Ⅲ C++ 預編譯 ## 符號的作用
## 用在define中作為連接符看待。可以將變數和已經寫好的內容聯合起來用,就像樓上那位說的
#define f(x) hello##x
這樣的定義 出來就是 hello4。如果解決你的問題 你就把連接符去掉應該就好了。這里寫法比較多但是不建議去掉,宏定義很容易出現語法錯誤而且不被編譯器檢查。。。。
Ⅳ 關於Const和Define的區別
一、表達意思不同
1、Const:n. 常量,常數; (Const)人名;(羅)康斯特
2、Define:vt. 定義;使明確;規定、n. (Define)人名;(英)德法恩;(葡)德菲內
二、詞性不同
1、Const:通常作名詞。
例句:Forstructuresannionstobe modifiablelvalues,theymust .
如果要使結構或者聯合類型為可更改左值,那麼它們不能包含任何具有常量屬性的成員。
2、Define:既可以作及物動詞,也可以作名詞。
例句:Sohow do youdefineit?
你是怎麼定義它的?
(4)預編譯標志符號擴展閱讀:
「Define」的近義詞:regulate
1、讀音:英[ˈreɡjuleɪt] 、美[ˈreɡjuleɪt]
2、表達意思:vt. 調節,規定;控制;校準;有系統地管理
3、相關短語:
REG regulate控制 ; 校準 ; 節制 ; 調節
Voltage regulate電壓調節方式 ; 電壓調節 ; 電壓調理方式 ; 速度調節
regulate blood調節血液 ; 規管血 ; 調節血 ; 正在翻譯
4、例句:Wehave tolearn toregulateemotionsinour life.
在生活中我們要學會調節自己的情緒。
Ⅳ 什麼是預編譯 何時需要預編譯 mfc面試
預編譯又稱為預處理,是做些代碼文本的替換工作
預編譯又稱為預處理,是做些代碼文本的替換工作
處理#開頭的指令,比如拷貝#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
Ⅵ C語言標識符的命名規則有哪些
C語言中把標識符分為三類:關鍵字,預定義標識符,用戶自定義標識符 。
C語言命名規則是:
1、標識符由字母(A-Z,a-z)、數字(0-9)、下劃線「_」組成,並且首字元不能是數字,但可以是字母或者下劃線。例如,正確的標識符:abc,a1,prog_to。
2、不能把C語言關鍵字作為用戶標識符,例如if ,for, while等.
3、標識符長度是由機器上的編譯系統決定的,一般的限制為8字元(註:8字元長度限制是C89標准,C99標准已經擴充長度,其實大部分工業標准都更長)。
4、標識符對大小寫敏感,即嚴格區分大小寫。一般對變數名用小寫,符號常量命名用大寫。
5、標識符命名應做到「見名知意」,例如,長度(length),求和、總計(sum),圓周率(pi)。
(6)預編譯標志符號擴展閱讀:
C語言特有特點:
1、C語言是一個有結構化程序設計、具有變數作用域(variable scope)以及遞歸功能的過程式語言。
2、C語言傳遞參數均是以值傳遞(pass by value),另外也可以傳遞指針(a pointer passed by value)。
3、不同的變數類型可以用結構體(struct)組合在一起。
4、只有32個保留字(reserved keywords),使變數、函數命名有更多彈性。
5、部份的變數類型可以轉換,例如整型和字元型變數。
6、通過指針(pointer),C語言可以容易的對存儲器進行低級控制。
7、預編譯處理(preprocessor)讓C語言的編譯更具有彈性。
Ⅶ #ifdef #ifndef 到底怎麼用
條件預編譯
#if, #ifdef, #ifndef, #else, #elif, #endif通過這6條預編譯指令可以簡單控制編譯器的行為,當文件被編譯時,可以使用這些命令來控制一些特定的行被編譯或不被編譯。
#if expression如果表達式為真,命令後邊的代碼被編譯。
#ifdef macro如果宏被使用#define 定義,命令後邊的代碼被編譯。
#ifndef macro如果宏沒有被使用#define 定義,命令後邊的代碼被編譯。
A few side notes: #elif 命令是一種縮略形式,它和」elseif」具有同樣的作用,你也可以在#if之後使用」defined」或者」!defined」來擴展功能。
下邊是一個例子:
#ifdef DEBUG
cout << "This is the test version, i=" << i << endl;
#else
cout << "This is the proction version!" << endl;
#endif你應該注意到,這個例子和在代碼中插入/刪除大量的」cout」語句相比,使調試變得更容易。
Ⅷ C語言中的預定義標識符
1.預定義標識符是C語言中標識符三種中的一種,在C語言中有特定的含義。如函數「printf」是「格式輸出」的英語全稱加縮寫。
2.標識符分為關鍵字、預定義標識符和用戶標識符。
3.預定義標識符是C語言中系統預先定義的標識符,如系統類庫名、系統常量名、系統函數名。預定義標識符具有見字明義的特點,如函數「格式輸出」(英語全稱加縮寫:printf)、「格式輸入」(英語全稱加縮寫:scanf)、sin、isalnum等等。預定義標識符可以作為用戶標識符使用,只是這樣會失去系統規定的原意,使用不當還會使程序出錯。
Ⅸ C語言提供的預編譯處理命令主要有哪三種
幾個預編譯指令的用法
預處理過程掃描源代碼,對其進行初步的轉換,產生新的源代碼提供給編譯器。可見預處理過程先於編譯器對源代碼進行處理。
在C語言中,並沒有任何內在的機制來完成如下一些功能:在編譯時包含其他源文件、定義宏、根據條件決定編譯時是否包含某些代碼。要完成這些工作,就需要使用預處理程序。盡管在目前絕大多數編譯器都包含了預處理程序,但通常認為它們是獨立於編譯器的。預處理過程讀入源代碼,檢查包含預處理指令的語句和宏定義,並對源代碼進行響應的轉換。預處理過程還會刪除程序中的注釋和多餘的空白字元。
預處理指令是以#號開頭的代碼行。#號必須是該行除了任何空白字元外的第一個字元。#後是指令關鍵字,在關鍵字和#號之間允許存在任意個數的空白字元。整行語句構成了一條預處理指令,該指令將在編譯器進行編譯之前對源代碼做某些轉換。下面是部分預處理指令:
指令
用途
#
空指令,無任何效果
#include
包含一個源代碼文件
#define
定義宏
#undef
取消已定義的宏
#if
如果給定條件為真,則編譯下面代碼
#ifdef
如果宏已經定義,則編譯下面代碼
#ifndef
如果宏沒有定義,則編譯下面代碼
#elif
如果前面的#if給定條件不為真,當前條件為真,則編譯下面代碼
#endif
結束一個#if……#else條件編譯塊
#error
停止編譯並顯示錯誤信息
一、文件包含
#include預處理指令的作用是在指令處展開被包含的文件。包含可以是多重的,也就是說一個被包含的文件中還可以包含其他文件。標准C編譯器至少支持八重嵌套包含。
預處理過程不檢查在轉換單元中是否已經包含了某個文件並阻止對它的多次包含。這樣就可以在多次包含同一個頭文件時,通過給定編譯時的條件來達到不同的效果。例如:
#define
AAA
#include
"t.c"
#undef
AAA
#include
"t.c"
為了避免那些只能包含一次的頭文件被多次包含,可以在頭文件中用編譯時條件來進行控制。例如:
#ifndef
MY_H
#define
MY_H
……
#endif
在程序中包含頭文件有兩種格式:
#include
<my.h>
#include
"my.h"
第一種方法是用尖括弧把頭文件括起來。這種格式告訴預處理程序在編譯器自帶的或外部庫的頭文件中搜索被包含的頭文件。第二種方法是用雙引號把頭文件括起來。這種格式告訴預處理程序在當前被編譯的應用程序的源代碼文件中搜索被包含的頭文件,如果找不到,再搜索編譯器自帶的頭文件。
採用兩種不同包含格式的理由在於,編譯器是安裝在公共子目錄下的,而被編譯的應用程序是在它們自己的私有子目錄下的。一個應用程序既包含編譯器提供的公共頭文件,也包含自定義的私有頭文件。採用兩種不同的包含格式使得編譯器能夠在很多頭文件中區別出一組公共的頭文件。
二、宏
宏定義了一個代表特定內容的標識符。預處理過程會把源代碼中出現的宏標識符替換成宏定義時的值。宏最常見的用法是定義代表某個值的全局符號。宏的第二種用法是定義帶參數的宏,這樣的宏可以象函數一樣被調用,但它是在調用語句處展開宏,並用調用時的實際參數來代替定義中的形式參數。
1.#define指令
#define預處理指令是用來定義宏的。該指令最簡單的格式是:首先神明一個標識符,然後給出這個標識符代表的代碼。在後面的源代碼中,就用這些代碼來替代該標識符。這種宏把程序中要用到的一些全局值提取出來,賦給一些記憶標識符。
#define
MAX_NUM
10
int
array[MAX_NUM];
for(i=0;i<MAX_NUM;i++)
在這個例子中,對於閱讀該程序的人來說,符號MAX_NUM就有特定的含義,它代表的值給出了數組所能容納的最大元素數目。程序中可以多次使用這個值。作為一種約定,習慣上總是全部用大寫字母來定義宏,這樣易於把程序紅的宏標識符和一般變數標識符區別開來。如果想要改變數組的大小,只需要更改宏定義並重新編譯程序即可。
宏表示的值可以是一個常量表達式,其中允許包括前面已經定義的宏標識符。例如:
#define
ONE
1
#define
TWO
2
#define
THREE
(ONE+TWO)
注意上面的宏定義使用了括弧。盡管它們並不是必須的。但出於謹慎考慮,還是應該加上括弧的。例如:
six=THREE*TWO;
預處理過程把上面的一行代碼轉換成:
six=(ONE+TWO)*TWO;
如果沒有那個括弧,就轉換成six=ONE+TWO*TWO;了。
宏還可以代表一個字元串常量,例如:
#define
VERSION
"Version
1.0
Copyright(c)
2003"
2.帶參數的#define指令
帶參數的宏和函數調用看起來有些相似。看一個例子:
#define
Cube(x)
(x)*(x)*(x)
可以時任何數字表達式甚至函數調用來代替參數x。這里再次提醒大家注意括弧的使用。宏展開後完全包含在一對括弧中,而且參數也包含在括弧中,這樣就保證了宏和參數的完整性。看一個用法:
int
num=8+2;
volume=Cube(num);
展開後為(8+2)*(8+2)*(8+2);
如果沒有那些括弧就變為8+2*8+2*8+2了。
下面的用法是不安全的:
volume=Cube(num++);
如果Cube是一個函數,上面的寫法是可以理解的。但是,因為Cube是一個宏,所以會產生副作用。這里的擦書不是簡單的表達式,它們將產生意想不到的結果。它們展開後是這樣的:
volume=(num++)*(num++)*(num++);
很顯然,結果是10*11*12,而不是10*10*10;
那麼怎樣安全的使用Cube宏呢?必須把可能產生副作用的操作移到宏調用的外面進行:
int
num=8+2;
volume=Cube(num);
num++;
3.#運算符
出現在宏定義中的#運算符把跟在其後的參數轉換成一個字元串。有時把這種用法的#稱為字元串化運算符。例如:
#define
PASTE(n)
"adhfkj"#n
main()
{
printf("%s\n",PASTE(15));
}
宏定義中的#運算符告訴預處理程序,把源代碼中任何傳遞給該宏的參數轉換成一個字元串。所以輸出應該是adhfkj15。
4.##運算符
##運算符用於把參數連接到一起。預處理程序把出現在##兩側的參數合並成一個符號。看下面的例子:
#define
NUM(a,b,c)
a##b##c
#define
STR(a,b,c)
a##b##c
main()
{
printf("%d\n",NUM(1,2,3));
printf("%s\n",STR("aa","bb","cc"));
}
最後程序的輸出為:
123
aabbcc
千萬別擔心,除非需要或者宏的用法恰好和手頭的工作相關,否則很少有程序員會知道##運算符。絕大多數程序員從來沒用過它。
三、條件編譯指令
條件編譯指令將決定那些代碼被編譯,而哪些是不被編譯的。可以根據表達式的值或者某個特定的宏是否被定義來確定編譯條件。
1.#if指令
#if指令檢測跟在製造另關鍵字後的常量表達式。如果表達式為真,則編譯後面的代碼,知道出現#else、#elif或#endif為止;否則就不編譯。
2.#endif指令
#endif用於終止#if預處理指令。
#define
DEBUG
0
main()
{
#if
DEBUG
printf("Debugging\n");
#endif
printf("Running\n");
}
由於程序定義DEBUG宏代表0,所以#if條件為假,不編譯後面的代碼直到#endif,所以程序直接輸出Running。
如果去掉#define語句,效果是一樣的。
3.#ifdef和#ifndef
#define
DEBUG
main()
{
#ifdef
DEBUG
printf("yes\n");
#endif
#ifndef
DEBUG
printf("no\n");
#endif
}
#if
defined等價於#ifdef;
#if
!defined等價於#ifndef
4.#else指令
#else指令用於某個#if指令之後,當前面的#if指令的條件不為真時,就編譯#else後面的代碼。#endif指令將中指上面的條件塊。
#define
DEBUG
main()
{
#ifdef
DEBUG
printf("Debugging\n");
#else
printf("Not
debugging\n");
#endif
printf("Running\n");
}
5.#elif指令
#elif預處理指令綜合了#else和#if指令的作用。
#define
TWO
main()
{
#ifdef
ONE
printf("1\n");
#elif
defined
TWO
printf("2\n");
#else
printf("3\n");
#endif
}
程序很好理解,最後輸出結果是2。
6.其他一些標准指令
#error指令將使編譯器顯示一條錯誤信息,然後停止編譯。
#line指令可以改變編譯器用來指出警告和錯誤信息的文件號和行號。
#pragma指令沒有正式的定義。編譯器可以自定義其用途。典型的用法是禁止或允許某些煩人的警告信息。
Ⅹ 編譯和預編譯有什麼區別。
預編譯又稱為預處理,是做些代碼文本的替換工作。
處理#開頭的指令,比如拷貝#include包含的文件代碼,#define宏定義的替換,條件編譯等
就是為編譯做的預備工作的階段
主要處理#開始的預編譯指令
編譯(compilation , compile) 1、利用編譯程序從源語言編寫的源程序產生目標程序的過程。 2、用編譯程序產生目標程序的動作。 編譯就是把高級語言變成計算機可以識別的2進制語言,計算機只認識1和0,編譯程序把人們熟悉的語言換成2進制的。