第一篇:【好程序員學(xué)習(xí)筆記】C語(yǔ)言 編譯預(yù)處理命令
文件包含:
把指定的文件插入到預(yù)處理命令行所在的位置并取代該命令行,即把指定的文件和當(dāng)前的源程序文件連接成一個(gè)源文件。#include<文件名>
在文件包含目錄中去查找指定的文件,并將該文件添加到源文件中。一個(gè)被包含的文件中可以含有文件包含命令來(lái)包含另一個(gè)文件。#include“文件名”
命令中文件名的位置是當(dāng)前源文件的位置,若在當(dāng)前目錄中未找到該文件,則再到“包含目錄”中去查找。
宏
用一個(gè)標(biāo)識(shí)符表示一個(gè)字符串,稱(chēng)為宏,被定義為宏的標(biāo)識(shí)符稱(chēng)為宏名。在編譯預(yù)處理時(shí)對(duì)程序中所有出現(xiàn)的宏名用宏定義中的字符串去代換,這就是宏替換。它是由系統(tǒng)編譯程序時(shí)自動(dòng)完成的。
無(wú)參宏定義
#define 標(biāo)識(shí)符 字符串 如
#define PI 3.14 使用宏時(shí)要注意:
(1)宏定義是用宏名來(lái)表示一個(gè)字符串,在宏展開(kāi)時(shí)用字符串取代宏名。
2)宏定義不是變量定義或語(yǔ)句,在行末不能加分號(hào),如果加上分號(hào)則分號(hào)也成為字符串的一部分。
(3)宏定義可以出現(xiàn)在程序的任何地方,其作用域是宏定義命令所在位置開(kāi)始到源程序結(jié)束。如果要終止其作用域可使用#undef命令。
(4)宏定義允許嵌套,在宏定義的字符串中可以使用已經(jīng)定義的宏名。在宏展開(kāi)時(shí)將逐層替換。
(5)#define PI 3.1415926 #define AREA PI*y*y 有參宏定義
#define 宏名(形參表)字符串
對(duì)帶參數(shù)的宏,在調(diào)用中不僅要進(jìn)行宏展開(kāi),而且還要用實(shí)參去替換形參。帶參宏調(diào)用的語(yǔ)法格式如下: 宏名(實(shí)參表); #define M(x)x+1 K=M(3);K=3+1 定義有參宏時(shí)要注意以下幾點(diǎn):
(1)有參宏定義中,宏名和形參表之間不能有空格出現(xiàn)。
(2)在函數(shù)中,調(diào)用時(shí)要把實(shí)參的值賦給形參,進(jìn)行“值傳遞”。而在帶參宏調(diào)用中,只是符號(hào)替換,不存在值傳遞問(wèn)題。
(3)宏定義中的形參只能是標(biāo)識(shí)符,而宏調(diào)用中的實(shí)參可以是表達(dá)式。
字符串內(nèi)的形參通常用括號(hào)括起來(lái)以避免出錯(cuò)。
在使用宏時(shí)不僅要將形式參數(shù)用括號(hào)括起來(lái),還應(yīng)將其整體用括號(hào)括起來(lái)。#define S(y)((y)*(y))條件編譯
條件編譯可以按不同的條件去編譯不同的程序段。1#ifdef #ifdef 標(biāo)識(shí)符 程序段1 #else 程序段2 #endif 功能:如果標(biāo)識(shí)符已被#define定義過(guò),則對(duì)程序段1進(jìn)行編譯,否則對(duì)程序段2進(jìn)行編譯。格式中的#else部分可以沒(méi)有,即: #ifdef 標(biāo)識(shí)符
程序段 #endif
2、#ifndef 語(yǔ)法格式如下: #ifndef 標(biāo)識(shí)符 程序段1
#else 程序段2 #endif 功能與ifdef形式的功能正好相反。
3、#if 常量表達(dá)式 #if 常量表達(dá)式 程序段1 #else 程序段2 #endif 功能:如果常量表達(dá)式的值為真(非0),則對(duì)程序段1進(jìn)行編譯,否則對(duì)程序段2進(jìn)行編譯,因此可以使程序在不同條件下,完成不同的功能。
上面介紹的條件編譯實(shí)現(xiàn)的邏輯也可以用條件語(yǔ)句來(lái)實(shí)現(xiàn),但是用條件語(yǔ)句將會(huì)對(duì)整個(gè)源程序進(jìn)行編譯,生成的目標(biāo)代碼程序較長(zhǎng),運(yùn)行時(shí)間也較長(zhǎng),采用條件編譯則根據(jù)條件只編譯其中的程序段1或程序段2,生成的目標(biāo)程序較短。
第二篇:C語(yǔ)言程序設(shè)計(jì)教案 第九章 編譯預(yù)處理
第九章 編譯預(yù)處理
課題:
教學(xué)目的: 教學(xué)重點(diǎn): 教學(xué)難點(diǎn): 第九章 編譯預(yù)處理
1、了解預(yù)處理的概念及特點(diǎn)
2、掌握有參宏與無(wú)參宏的定義及使用,領(lǐng)會(huì)文件包含的使用及效果 掌握宏的使用,文件包含 有參宏與無(wú)參宏的使用
步驟一 復(fù)習(xí)引導(dǎo)
ANSI C標(biāo)準(zhǔn)規(guī)定可以在C源程序中加入一些“預(yù)處理命令”,以改進(jìn)程序設(shè)計(jì)環(huán)境,提高編程效率。
這些預(yù)處理命令是由ANSI C統(tǒng)一規(guī)定的,但它不是C語(yǔ)言本身的組成部分,不能直接對(duì)它們進(jìn)行編譯。必須在對(duì)程序進(jìn)行通常的編譯之前,先對(duì)程序中這些特殊的命令進(jìn)行“預(yù)處理”,即根據(jù)預(yù)處理命令對(duì)程序作相應(yīng)的處理。經(jīng)過(guò)預(yù)處理后程序不再包括預(yù)處理命令了,最后再由編譯程序?qū)︻A(yù)處理后的源程序進(jìn)行通常的編譯處理,得到可供執(zhí)行的目標(biāo)代碼。
步驟二 講授新課
C語(yǔ)言與其他高級(jí)語(yǔ)言的一個(gè)重要區(qū)別是可以使用預(yù)處理命令和具有預(yù)處理的功能。C提供的預(yù)處理功能主要有以下三種: 宏定義、文件包含、條件編譯。
分別用宏定義命令、文件包含命令、條件編譯命令來(lái)實(shí)現(xiàn)。為了與一般C語(yǔ)句相區(qū)別,這些命令以符號(hào)“ #” 開(kāi)頭。
§9.1宏定義
宏: 代表一個(gè)字符串的標(biāo)識(shí)符。
宏名:被定義為“宏”的標(biāo)識(shí)符。
宏代換(展開(kāi)):在編譯預(yù)處理時(shí),對(duì)程序中所有出現(xiàn)的 “宏名”,用宏定義中的字符串去代換的過(guò)程。
一、不帶參數(shù)的宏定義
一般形式:
#define
標(biāo)識(shí)符
字符串
#define PI 3.1415926
main()
{ float l, s, r, v;
printf(“input radius:”);
scanf(“%f”, &r);
l = 2.0*PI*r;
s = PI*r*r;
v = 3.0/4*PI*r*r*r;
printf(“%10.4f,%10.4f,%10.4n”, l, s, v);
}
例如:由鍵盤(pán)輸入y值,求表達(dá)式:
3(y2+3y)+ 4(y2+3y)+ y(y2+3y)#define M(y*y+3*y)main(){ int s, y;
printf(“Input a number :”);scanf(“%d”,&y);
s=3*M+4*M+y*M;
printf(“s=%dn”,s);} 先宏展開(kāi):s=3*(y*y+3*y)+4*(y*y+3*y)+ y*(y*y+3*y)再與源程序合并
說(shuō)明:
⑴宏名一般用大寫(xiě)表示,以便與變量名區(qū)分。⑵使用宏名使程序易讀,易修改。⑶只作簡(jiǎn)單的置換,不作正確性檢查。⑷宏定義不是C語(yǔ)句,不必在行末加分號(hào)。
⑸宏名的作用域一般從自定義命令到本源文件結(jié)束。⑹可以用# undef命令終止宏定義的作用域。⑺宏定義允許嵌套,允許層層置換。
⑻宏名在源程序中用雙引號(hào)括起來(lái),則TC中預(yù)處理不對(duì)其作宏代換。
例: printf(“L=%f”, L);中雙引號(hào)內(nèi)L不替換。
⑼宏定義與定義的變量不同,宏只作字符替換,不分配內(nèi)存空間。⑽對(duì)“輸出格式”進(jìn)行宏定義,可以減少書(shū)寫(xiě)麻煩 例如:
#define P printf #define D “%d,%d,%dn”
#define F “%6.2f,%6.2f,%6.2fn” main(){ int a=5,c=8,e=11;
float b=3.8,d=9.7;f=21.08;
P(D,a,c,e);
P(F,b,d,f);
P(F,a+b,c+d,e+f);}
二、帶參數(shù)的宏定義
格式:#define
宏名(參數(shù)表)字符串
例:#define s(a,b)a*b
{……
area =s(3,2);
……}
對(duì)帶參的宏展開(kāi)后,為area=3*2;
例: #define M(y)y*y+3*y
{……
k=M(5);
……}
對(duì)其展開(kāi)后,為k=5*5+3*5;
說(shuō)明:
⑴對(duì)帶參數(shù)的宏展開(kāi)只是將宏名后括號(hào)內(nèi)的實(shí)參
字符串代替#define命令行中的形參。
⑵宏定義時(shí),在宏名與帶參數(shù)的括號(hào)之間不應(yīng)加
空格,否則將空格以后的字符都作為替代字符
串的一部分。
⑶帶參宏定義,形參不分配內(nèi)存單元,因此不必
作類(lèi)型定義。(與函數(shù)的區(qū)別之一)⑷帶參宏與函數(shù)的區(qū)別之二:
例如: main(){ int i=1;
while(i<=5)
printf(“%dt”,SQ(i++));} SQ(int y){ return(y)*(y);} 其結(jié)果為:1
如:
#define SQ(y)((y)*(y))main(){ int i =1;
while(i<=5)
printf(“%dt”,SQ(i++));} 運(yùn)行結(jié)果: 2 12 30
例:利用宏定義求兩個(gè)數(shù)中的大數(shù)。
#define MAX(a,b)(a>b)?a:b main(){int x, y, max;
scanf(“%d%d”, &x, &y);
max =MAX(x, y);
printf(“max=%dn”, max);} 帶參的宏定義和函數(shù)不同:
1、函數(shù)調(diào)用時(shí),先求實(shí)參表達(dá)式值,后代入。而帶參的宏只是進(jìn)行簡(jiǎn)單的字符替換。
2、函數(shù)調(diào)用是在程序運(yùn)行時(shí)處理的,分配臨時(shí)的內(nèi)存單元。而宏展開(kāi)則是在編譯時(shí)進(jìn)行的,不分配內(nèi)存單元,不進(jìn)行值的傳遞,也無(wú)“返回值”。
3、對(duì)函數(shù)中的實(shí)參和形參都要定義類(lèi)型,類(lèi)型應(yīng)一致。而宏不存在類(lèi)型問(wèn)題,宏名和參數(shù)無(wú)類(lèi)型,只是一個(gè)符號(hào)代表,展開(kāi)時(shí)代入指定的字符即可。
4、調(diào)用函數(shù)只可得到一個(gè)返回值,而用宏可以設(shè)法得到幾個(gè)結(jié)果。
5、使用宏次數(shù)多時(shí),宏展開(kāi)后使源程序增長(zhǎng),而函數(shù)調(diào)用不使源程序變長(zhǎng)。
6、宏替換不占運(yùn)行時(shí)間,只占編譯時(shí)間。
而函數(shù)調(diào)用則占用運(yùn)行時(shí)間(分配單元、保留現(xiàn)場(chǎng)、值傳遞、返回)一般用宏代表簡(jiǎn)短的表達(dá)式比較合適。
也可利用宏定義實(shí)現(xiàn)程序的簡(jiǎn)化。例9.5:
#define PR printf #define NL “n” #define D “%d” #define D1 D NL #define D2 D D NL #define D3 D D D NL #define D4 D D D D NL #define S “%s” main(){ int a,b,c,d;
char string[]=“CHINA”;
a=1;b=2;c=3;d=4;
PR(D1,a);
PR(D2,a,b);
PR(D3,a,b,c);
PR(D4,a,b,c,d);
PR(S, string);}
§9.2 “文件包含”處理
“文件包含”處理是指將指定的被包含文件的全部?jī)?nèi)容插到該控制行的位置處,使其成為源文件的一部分參與編譯。因此,被包含的文件應(yīng)該是源文件。通常置于源程序文件的首部,故也稱(chēng)為“頭文件”。
C編譯系統(tǒng)提供的頭文件擴(kuò)展名為“.h”,但設(shè)計(jì)者可根據(jù)實(shí)際情況,自行確定包含文件的后綴、名字及其位置。
一般形式,#include “文件名”
或
#include <文件名>
文件format.h
#define PR printf #define NL “n” #define D “%d” #define D1 D NL #define D2 D D NL #define D3 D D D NL #define D4 D D D D NL #define S “%s” 文件file1.c #include “format.h” main(){ int a,b,c,d;
char string[]=“CHINA”;
a=1;b=2;c=3;d=4;
PR(D1,a);
PR(D2,a,b);
PR(D3,a,b,c);
PR(D4,a,b,c,d);
PR(S, string);} 注:被包含的文件應(yīng)是源文件,而不應(yīng)是目標(biāo)文件。
頭文件除了可以包含函數(shù)原型和宏定義外,也可以包括結(jié)構(gòu)體類(lèi)型定義和全局變量定義等。說(shuō)明:
1、一個(gè)include命令只能指定一個(gè)被包含文件,如果要包含n個(gè)文件,要用n個(gè)include命令。
2、如果文件1包含文件2,而文件2中要用到文件3的內(nèi)容,則可在文件1中用兩個(gè)include命令分別包含文件2和文件3,而且文件3應(yīng)出現(xiàn)在文件2之前,即在“file1.c”中定義:
#include “file3.h”
#include “file2.h”
3、在一個(gè)被包含文件中又可以包含另一個(gè)被包含文件,即文件包含是可以嵌套的。
4、被包含文件(file2.h)與其所在的文件(file1.c),在預(yù)編譯后已成為同一個(gè)文件。
5、在#include 命令中,文件名可以用雙引號(hào)或尖括號(hào)括起來(lái)。
如: #include
或
#include “file2.h” 二者的區(qū)別:
用尖括號(hào)時(shí)稱(chēng)為標(biāo)準(zhǔn)方式,系統(tǒng)到存放C庫(kù)頭文件所在的目錄中尋找要包含的文件。
用雙引號(hào)時(shí),系統(tǒng)先在用戶當(dāng)前目錄中尋找要包含的文件,若找不到,再按標(biāo)準(zhǔn)方式查找。#include “c:tcincludemyfile.h”
/*正確*/ #include
/*正確*/ #include
/*錯(cuò)誤*/
用尖括號(hào):帶路徑:按指定路徑去尋找被包含文件,但此時(shí)被包含文件不能以“.h”結(jié)尾,否則錯(cuò)誤。
不帶路徑:僅從指定標(biāo)準(zhǔn)目錄下找。
用引號(hào): 帶路徑:按指定路徑去尋找被包含文件,不再?gòu)漠?dāng)前目錄和指定目錄下找。
不帶路徑:先在當(dāng)前目錄下找,找不到再在系統(tǒng)指定的標(biāo)準(zhǔn)目錄下找。
步驟三 課堂小結(jié)
本課主要講解了宏定義、“文件包含”處理。對(duì)帶參數(shù)的宏的使用,及與函數(shù)的使用的區(qū)別。搞清經(jīng)常使用的頭文件。
步驟四 布置作業(yè) 上機(jī)作業(yè):(第九章課后練習(xí))9.4 書(shū)面作業(yè):(第九章課后練習(xí))9.7、9.8
第三篇:C語(yǔ)言的預(yù)處理命令有哪些?
問(wèn):關(guān)于C語(yǔ)言中的預(yù)處理命令? 答:
我們可以在C源程序中插入傳給編譯程序的各種指令,這些指令被稱(chēng)為預(yù)處理器指令(等價(jià)于匯編語(yǔ)言中的偽指令),它們擴(kuò)充了程序設(shè)計(jì)的環(huán)境。
現(xiàn)把常用的預(yù)處理命令總結(jié)如下:
1.預(yù)處理程序
按照ANSI標(biāo)準(zhǔn)的定義,預(yù)處理程序應(yīng)該處理以下12條指令:
#if、#ifdef、#ifndef、#else、#elif、#endif、#define、#undef、#line、#error、#pragma、#include。
顯然,所有的12個(gè)預(yù)處理指令都以符號(hào)#開(kāi)始,每條預(yù)處理指令必須獨(dú)占一行。2.#define #define指令定義一個(gè)標(biāo)識(shí)符和一個(gè)串(也就是字符集),在源程序中發(fā)現(xiàn)該標(biāo)識(shí)符時(shí),都用該串替換之(原樣替換,不要附加任何人為理解上的符號(hào))。這種標(biāo)識(shí)符稱(chēng)為宏名字,相應(yīng)的替換稱(chēng)為宏代換。一般形式如下:
#define macro-name char-sequence 這種語(yǔ)句不用分號(hào)結(jié)尾。宏名字和串之間可以有多個(gè)空格符,但串開(kāi)始后只能以新行終止。在C語(yǔ)言里宏定義只用來(lái)做的宏名替換,而不做語(yǔ)法檢查的,因而它不是C語(yǔ)句,所以宏定義的語(yǔ)句結(jié)尾不需要加分號(hào)。
宏也在C里也叫預(yù)處理命令,因?yàn)楹晔窃诔绦蚓幾g前先進(jìn)行字符替換的,所以叫預(yù)處理.例如:我們使用LEFT代表1,用RIGHT代表0,我們使用兩個(gè)#define指令:
#define LEFT 1 #define RIGHT 0 每當(dāng)在源程序中遇到LEFT或RIGHT時(shí),編譯程序都用1或0替換。定義一個(gè)宏名字之后,可以在其他宏定義中使用,例如:
#define ONE 1 #define TWO ONE+ONE #define THREE ONE+TWO 宏代換就是用相關(guān)的串替代標(biāo)識(shí)符。因此,如果希望定義一條標(biāo)準(zhǔn)錯(cuò)誤信息時(shí),可以如下定義:
#define ERROR_MS “Standard error on input n” 如果一個(gè)串長(zhǎng)于一行,可在行尾用反斜線””續(xù)行,如下:
#define LONG_STRING “This is a very very long
string that is used as an example”
3.#error
#error指令強(qiáng)制編譯程序停止編譯,它主要用于程序調(diào)試(放在錯(cuò)誤的分支中,一旦進(jìn)入錯(cuò)誤的分支就顯示該信息)。
#error指令的一般形式是:
#error error-message 注意,宏串error-message不用雙引號(hào)包圍。遇到#error指令時(shí),錯(cuò)誤信息被顯示,可能同時(shí)還顯示編譯程序作者預(yù)先定義的其他內(nèi)容。
4.#include 程序中的#include指令要求編譯程序讀入另一個(gè)源文件。被讀入文件的名字必須用雙引號(hào)(“”)或一對(duì)尖括號(hào)(<>)包圍,例如:
#include “stdio.h” #include
包含文件中可以包含其他#include指令,稱(chēng)為嵌套包含。允許的最大嵌套深度隨編譯器而變。文件名被雙括號(hào)或尖括號(hào)包圍決定了對(duì)指定文件的搜索方式。文件名被尖括號(hào)包圍時(shí),搜索按編譯程序作者的定義進(jìn)行,一般用于搜索某些專(zhuān)門(mén)放置包含文件的特殊目錄。當(dāng)文件名被雙引號(hào)包圍時(shí),搜索按編譯程序?qū)崟r(shí)的規(guī)定進(jìn)行,一般搜索當(dāng)前目錄。如未發(fā)現(xiàn),再按尖括號(hào)包圍時(shí)的辦法重新搜索一次。
通常,絕大多數(shù)程序員使用尖括號(hào)包圍標(biāo)準(zhǔn)的頭文件,雙引號(hào)用于包圍與當(dāng)前程序相關(guān)的文件名。
5.條件編譯指令
若干編譯指令允許程序員有選擇的編譯程序源代碼的不同部分,這種過(guò)程稱(chēng)為條件編譯。5.1 #if、#else、#elif #endif 條件編譯指令中最常用的或許是#if,#else,#elif和#endif。這些指令允許程序員根據(jù)常數(shù)表達(dá)式的結(jié)果有條件地啟用(包圍)部分代碼。
#if的一般形式是:
#if constant-expression Statement sequence #endif 如#if后的常數(shù)表達(dá)式為真,則#if和#endif中間的代碼被編譯,否則忽略該代碼段。#endif標(biāo)記#if塊的結(jié)束。
#else指令的作用與C語(yǔ)言的else相似,#if指令失敗時(shí)它可以作為備選指令。例如:
#include
#if MAX>99 printf(“Compiled for array greater than 99.n”);#else printf(“Complied for small array.n”);#endif return 0;} 注意,#else既是標(biāo)記#if塊的結(jié)束,也標(biāo)記#else塊的開(kāi)始。因?yàn)槊總€(gè)#if只能寫(xiě)一個(gè)#endif匹配。#elif指令的意思是“否則,如果”,為多重編譯選擇建立一條if-else-if(如果-否則-如果鏈)。如果#if表達(dá)式為真,該代碼塊被編譯,不測(cè)試其他#elif表達(dá)式。否則,序列中的下一塊被測(cè)試,如果成功則編譯之。一般形式如下:
#if expression 1 Statement sequence 1 #elif expression 2 Statement sequence 2 #elif expression 3 Statement sequence 3 …
#elif expression n Statement sequence n #endif 5.2 #ifdef 和 #ifndef
條件編譯的另一個(gè)方法是使用編譯指令#ifdef和#ifndef,分別表示“如果已定義”和“如果未定義”。#ifdef的一般形式如下:
#ifdef macro-name Statement sequence #endif 如果macro-name原先已經(jīng)被一個(gè)#define語(yǔ)句定義,則編譯其中的代碼塊。#ifndef的一般形式是:
#ifndef macro-name Statement sequence #endif 如果macro-name當(dāng)前未被#define語(yǔ)句定義,則編譯其中的代碼塊。
我認(rèn)為,用這種方法可以很方便的開(kāi)啟/關(guān)閉整個(gè)程序的某項(xiàng)特定功能。
?? #ifdef和#ifndef都可以使用#else或#elif語(yǔ)句。
#inlucde
#undef指令刪除前面定義的宏名字。也就是說(shuō),它的意思是“不要已定義的某個(gè)宏”。一般形式為:
#undef macro-name 7.使用defined 除#ifdef之外,還有另外一種確定是否定義宏名字的方法,即可以將#if指令與defined編譯時(shí)操作符一起使用。defined操作符的一般形式如下:
defined macro-name 如果macro-name是當(dāng)前定義的,則表達(dá)式為真,否則為假。例如,確定宏MY是否定義,可以使用下列兩種預(yù)處理命令之一:
#if defined MY 或
#ifdef MY 也可以在defined之前加上感嘆號(hào)”!”來(lái)反轉(zhuǎn)相應(yīng)的條件。例如,只有在DEBUG未定義的情況下才編譯。
#if!defined DEBUG Printf(“Final Version!n”);#endif 使用defined的一個(gè)原因是,它允許由#elif語(yǔ)句確定的宏名字存在。??? 8.#line #line指令改變__LINE__和__FILE__的內(nèi)容。__LINE__和__FILE__都是編譯程序中預(yù)定義的標(biāo)識(shí)符(見(jiàn)11)。標(biāo)識(shí)符__LINE__的內(nèi)容是當(dāng)前被編譯代碼行的行號(hào),__FILE__的內(nèi)容是當(dāng)前被編譯源文件的文件名。#line的一般形式是:
#line number “filename”
其中,number是正整數(shù)并變成__LINE__的新值;可選的“filename”是合法文件標(biāo)識(shí)符并變成__FILE__的新值。#line主要用于調(diào)試和特殊應(yīng)用。
9.#pragma
#pragma是編譯程序?qū)崿F(xiàn)時(shí)定義的指令,它允許由此向編譯程序傳入各種指令。例如,一個(gè)編譯程序可能具有支持跟蹤程序執(zhí)行的選項(xiàng),此時(shí)可以用#pragma語(yǔ)句選擇該功能。編譯程序忽略其不支持的#pragma選項(xiàng)。#pragma提高C源程序?qū)幾g程序的可移植性。
10.預(yù)處理操作符#和## 有兩個(gè)預(yù)處理操作符:#和##,它們可以在#define中使用。
操作符#通常稱(chēng)為字符串化的操作符,它把其后的串變成用雙引號(hào)包圍的串。例如: #include
Printf(“I like C”);
操作符##把兩個(gè)標(biāo)記拼在一起,形成一個(gè)新標(biāo)記。例如: #include
Printf(“%d”,xy);
操作符#和##主要作用是允許預(yù)處理程序?qū)Ω赌承┨厥馇闆r,多數(shù)程序中并不需要。11.預(yù)定義宏
C規(guī)范了5個(gè)固有的預(yù)定義宏,它們是: __LINE__:正在編譯的程序的行號(hào) __FILE__:正在編譯的程序的文件名
__DATE__:代表源文件翻譯成目標(biāo)碼的日期,形如month/day/year(月/日/年)__TIME__:代表源代碼編譯成目標(biāo)碼的時(shí)間,形如hour:minute:second(時(shí):分:秒)__STDC__:如果__STDC__的內(nèi)容是十進(jìn)制常數(shù)1,則表示編譯程序的實(shí)現(xiàn)符合標(biāo)準(zhǔn)C。
問(wèn):在程序的一行上可以出現(xiàn)多個(gè)有效的預(yù)處理命令行。預(yù)處理命令可以出現(xiàn)在函數(shù)的內(nèi)部。給出的兩段代碼,有一段是錯(cuò)誤的,哪段???
答:
第1段有問(wèn)題。#ifndef WIN32 #endif printf(“OKn”);在這里,這個(gè)printf就不會(huì)被執(zhí)行。也就是說(shuō),一行中,只能有一條預(yù)處理指令,當(dāng)編譯的預(yù)處理階段,編譯器識(shí)別了一條完整的預(yù)處理指令后,后面的所有東西他都不要了。
對(duì)于第二段,在函數(shù)里,我們是可以使用預(yù)處理指令的。比如:
void fun(void){ #ifdef WIN32...// 對(duì)于windows系統(tǒng)環(huán)境的操作 #else...// 對(duì)于windows以外的系統(tǒng)環(huán)境的操作
#endif /* WIN32 */...}
問(wèn):兩個(gè)C語(yǔ)言的小問(wèn)題(預(yù)處理命令)1.#define abc(x,y)(x)<(y)?(x):(y)main(){ int a=10,b=15,c;c=10*abc(a,b);printf(“%d”,c);} 我算出結(jié)果是100,可參考答案是15,不知是為什么? 2.#define A 5.5 #define B(x)A*x*x main(){ int a=1,b=2;;printf(“%f”,B(a+b));} 這個(gè)答案是9.5,這又是為何?
答:
1.c = 10*abc(a,b)= 10 *(x)<(y)?(x):(y)= 10 * 10 < 15 ? 10 : 15 = 100 < 15 ? 10 : 15 = 15 2.B(a+b)= A * a+b * a+b = 5.5 * 1 + 2 * 1 + 2 = 5.5 + 2 + 2 = 9.5
問(wèn):C語(yǔ)言預(yù)處理命令#define 選擇題:以下程序的運(yùn)行結(jié)果是?
#define MAX(A,B)(A)>(B)?(A):(B)#define PRINT(Y)printf(“Y=%dt”,Y)main(){ int a=1,b=2,c=3,d=4,t;t=MAX(a+b,c+d);PRINT(t);} A)Y=3 B)存在語(yǔ)法錯(cuò)誤 C)Y=7 D)Y=0 請(qǐng)給我解釋下PRINT(t);在宏展開(kāi)是怎么表示的,答案是C。
答:宏處理的時(shí)候,一定要記住:直接代進(jìn)去,任何多余的動(dòng)作都不能有(別想當(dāng)然地加括號(hào)?。?。
還有記住一點(diǎn)的是在printf“"雙括號(hào)里的是不能替代的話,所以這里的Y是輸出形式。而不是字符常量Y的替代。這是一種特殊規(guī)定。
PRINT(t)=printf(”Y=%dt“,t);所以結(jié)果必將是Y=(一個(gè)值)又因?yàn)?/p>
MAX(a+b,c+d)(a+b)>(c+d)?(a+b):(c+d)的結(jié)果是7,所以,答案是“C)Y=7”。
問(wèn):求解:關(guān)于c語(yǔ)言中,宏定義的問(wèn)題。。#define NLMSG_ALIGNTO 4 #define NLMSG_ALIGN(len)(((len)+ NLMSG_ALIGNTO1))這句編譯沒(méi)錯(cuò),請(qǐng)問(wèn) NLMSG_ALIGNN(len)的值是多少
答: 1.第一句定義了一個(gè)符號(hào)常量,值為4。隱含的作用是指定地址對(duì)齊方式:按4邊界對(duì)齊。
例如若某個(gè)對(duì)象的長(zhǎng)度為18,那么在為其分配空間時(shí),通過(guò)NLMSG_ALIGN宏就可以計(jì)算出最接近其的4的倍數(shù)為((18+4-1)& ~(3))= 20,這樣便為其申請(qǐng)/分配20字節(jié)空間。
這是32位微控制器/微處理器中,為了防止非對(duì)齊操作產(chǎn)生Exception(異常)而添加的保護(hù)措施。
2.第二句定義了一個(gè)宏,宏體是一個(gè)表達(dá)式
3.NLMSG_ALIGNN(len)是宏調(diào)用,具體做法就是單純地把字符用符號(hào)常量的值替換掉(宏展開(kāi))。宏展開(kāi)的結(jié)果就是(((len)+ 41))。要說(shuō)一下 &~,&是與運(yùn)算,~是取反,都是對(duì)二進(jìn)制”位"的操作。這里&~在一起,意思是“與3的非”。比如 5&~3 那么結(jié)果就是4(用2進(jìn)制數(shù)表達(dá)就是:101&~011那么就是101&100,結(jié)果是2進(jìn)制的100)。
問(wèn): 答:
問(wèn):
答:
第四篇:《c語(yǔ)言程序設(shè)計(jì)新視角》第九章編譯預(yù)處理小結(jié)
《c語(yǔ)言程序設(shè)計(jì)新視角》第九章 編譯預(yù)處理小結(jié) 編譯是把語(yǔ)句翻譯成機(jī)器碼,預(yù)編譯是在譯碼前進(jìn)行的處理法,文件包含把已有的文件為我所用來(lái)添加,宏定義的作用是替換,方便程序編輯的好方法,條件編譯可實(shí)現(xiàn)按需編譯,方便調(diào)試讓代碼適應(yīng)性更佳。
第五篇:黑馬程序員C語(yǔ)言教程: CC++培訓(xùn)專(zhuān)家-預(yù)處理命令使用詳解
傳智播客C/C++培訓(xùn)專(zhuān)家:預(yù)處
理命令詳解
作為一枚C/C++程序猿,在我們編寫(xiě)和查看C/C++源代碼的過(guò)程中會(huì)遇到各種編譯指令,這些指令稱(chēng)為預(yù)處理命令。預(yù)處理命令雖然不是C/C+的一部分,但卻擴(kuò)展了C程序的設(shè)計(jì)環(huán)境,下面?zhèn)髦遣タ虲/C+培訓(xùn)專(zhuān)家將向大家介紹如何應(yīng)用預(yù)處理程序和注釋簡(jiǎn)化程序開(kāi)發(fā)過(guò)程,并提高程序的可讀性。
ANSI標(biāo)準(zhǔn)定義的C語(yǔ)言所有預(yù)處理命令均以符號(hào)#開(kāi)頭,比如我寫(xiě)程序時(shí)常用的:
#define,#undef,#include,#if,#else,#elif,#endif,#ifdef,#ifndef, #error 1.#define和 #undef 宏定義命令的一般形式為:
#define[MacroName][MacroValue],示例如下: #defineITHEIMA 傳智播客黑馬程序員
在源程序中每次遇到ITHEIMA時(shí),均以定義的值傳智播客黑馬程序員代換它。
? 在使用該宏時(shí),有以下幾點(diǎn)注意事項(xiàng):
? 該語(yǔ)句沒(méi)有分號(hào)。在標(biāo)識(shí)符和串之間可以有任意個(gè)空格。? 定義宏的時(shí)候,可以使用之前已經(jīng)定義好的宏。
? 如果串長(zhǎng)于一行,可以在該行末尾用一反斜杠' '續(xù)行。
#defineLONG_STRING“good good study,day day up!” ? 在定義宏標(biāo)識(shí)符時(shí),字母一般需要大寫(xiě)。? 預(yù)處理運(yùn)算符的使用:
? #--該符號(hào)是“字符串化”的意思,出現(xiàn)在宏定義中的#是把跟在后面的參數(shù)轉(zhuǎn)換成一個(gè)字符串
#define ERROR_LOG(module)
fprintf(stderr, “error: ”#module“n”)ERROR_LOG(“add”);轉(zhuǎn)換為 fprintf(stderr,“error: ”add“n”);ERROR_LOG(devied =0);轉(zhuǎn)換為 fprintf(stderr,“error: devied=0n”);? ##--是連接符號(hào),將多個(gè)串連接到一起。char *szStr = “傳播播客_黑馬程序員”;#define ITCAST(exp)cout < 2.#include 命令#i nclude使編譯程序?qū)⒘硪辉次募度霂в校nclude的源文件,被讀入的源文件必須用雙引號(hào)或尖括號(hào)括起來(lái)。例如: #include“stdio.h”或者#include 這兩行代碼均使用C編譯程序讀入并編譯用于處理磁盤(pán)文件庫(kù)的子程序。將文件嵌入#i nclude命令中的文件內(nèi)是可行的,這種方 式稱(chēng)為嵌套的嵌入文件,嵌套層次依賴(lài)于具體實(shí)現(xiàn)。 ? 如果顯式路徑名為文件標(biāo)識(shí)符的一部分,則僅在那些子目錄中搜索被嵌入文件。 例如: #include “../include/head.h” ? 如果文件名用雙引號(hào)括起來(lái),則首先檢索當(dāng)前工作目錄。如果未發(fā)現(xiàn)文件,則在命令行中說(shuō)明的所有目錄中搜索。如果仍未發(fā)現(xiàn)文件,則搜索實(shí)現(xiàn)時(shí)定義的標(biāo)準(zhǔn)目錄。例如: include “head.h” ? 如果文件名被尖括號(hào)括起來(lái),則首先在編譯命令行中的目錄內(nèi)檢索。如果文件沒(méi)找到,則檢索標(biāo)準(zhǔn)目錄,不檢索當(dāng)前工作目錄。 例如: include
它與#endif之間的代碼,否則跳過(guò)這些代碼。命令#endif標(biāo)識(shí)一個(gè)#if塊的結(jié)束。
跟在#if后面的表達(dá)式在編譯時(shí)求值,因此它必須僅含常量及已定義過(guò)的標(biāo)識(shí)符,不可使用變量。表達(dá)式不許含有操作符sizeof(sizeof也是編譯時(shí)求值)。
? #else命令的功能有點(diǎn)象C語(yǔ)言中的else;#else建立另一選擇(在#if失敗的情況下)。注意,#else屬于#if塊。
? #elif命令意義與ELSE IF 相同,它形成一個(gè)if else-if階梯狀語(yǔ)句,可進(jìn)行多種編譯選擇。#elif 后跟一個(gè)常量表達(dá)式。如果表達(dá)式為true,則編譯其后的代碼塊,不對(duì)其它#elif表達(dá)式進(jìn)行測(cè)試。否則,順序測(cè)試下一塊。?
4.#error 命令#error強(qiáng)迫編譯程序停止編譯,主要用于程序調(diào)試。該指令使預(yù)處理器發(fā)出一條錯(cuò)誤消息,該消息包含指令中的文本.這條指令的目的就是在程序崩潰之前能夠給出一定的信息。
5.#ifdef 和 #ifndef 條件編譯的另一種方法是用#ifdef與#ifndef命令,它們分別表示“如果有定義”及“如果無(wú)定義”。# ifdef的一般形式是:
# ifdef macroname statement sequence
#endif #ifdef與#ifndef可以用于#if、#else,#elif語(yǔ)句中,但必須與一個(gè)#endif。
define MAX 91 #include
int main(){ #ifdef MAX cout<<“hello,MAX!”< #else cout<<“where is MAX?”< #endif #ifndef LEO cout<<“LEO is not defined”< #endif return 0;} 今天關(guān)于預(yù)處理命令的知識(shí)點(diǎn)傳智播客C/C+培訓(xùn)專(zhuān)家就為大家接受到這里, 歡迎大家留言交流.