- 青島雅思—專家談雅思考試發(fā)展趨勢(shì)
- 河南2011上半年自考網(wǎng)上報(bào)名入口 點(diǎn)擊進(jìn)入
- 2011年廣東省護(hù)士資格考試報(bào)名現(xiàn)場(chǎng)確認(rèn)時(shí)間
- 2011上半年樂山五通橋區(qū)會(huì)計(jì)從業(yè)考試報(bào)名3月10日-4月1
- 哈爾濱香坊區(qū)2011護(hù)士資格考試報(bào)名現(xiàn)場(chǎng)確認(rèn)時(shí)間
- 2011什邡第一次會(huì)計(jì)從業(yè)資格考試報(bào)名3月1日-4月15日
- 2011什邡第二次會(huì)計(jì)從業(yè)資格考試報(bào)名7月1日-9月16日
- 2011年中山市護(hù)士資格考試報(bào)名工作的通知
- 長(zhǎng)安大學(xué)2011考研成績(jī)查詢?nèi)肟?點(diǎn)擊進(jìn)入
- 西華大學(xué)2011考研成績(jī)查詢?nèi)肟?點(diǎn)擊進(jìn)入
- 中國(guó)地質(zhì)大學(xué)(武漢)2011考研成績(jī)3月3日查詢
- 中南民族大學(xué)2011考研成績(jī)查詢3月4日開始
- 沈陽(yáng)建筑大學(xué)2011考研成績(jī)查詢?nèi)肟?點(diǎn)擊進(jìn)入
- 沈陽(yáng)工業(yè)大學(xué)2011考研成績(jī)查詢?nèi)肟?點(diǎn)擊進(jìn)入
【武漢華嵌】關(guān)于高級(jí)編譯預(yù)處理的幾種用法
來(lái)源:求學(xué)問校網(wǎng) 發(fā)表時(shí)間:2011-12-09 瀏覽 57 次
作者:武漢華嵌技術(shù)部
C程序的源代碼中可包括各種編譯指令,這些指令稱為預(yù)處理命令。雖然它們實(shí)際上不是C語(yǔ)言的一部分,但卻擴(kuò)展了C程序設(shè)計(jì)的環(huán)境。本節(jié)將介紹如何應(yīng)用預(yù)處理程序和注釋簡(jiǎn)化程序開發(fā)過(guò)程,并提高程序的可讀性。
一、C宏體中出現(xiàn)的#,#@,##:
1、#的功能是將其后面的宏參數(shù)進(jìn)行字符串化操作(Stringfication)
2、##被稱為連接符(concatenator),用來(lái)將兩個(gè)Token連接為一個(gè)Token。
3、#@的功能是將其后面的宏參數(shù)進(jìn)行字符化。
以下是應(yīng)用的代碼:
#include <stdio.h>
#define Conn(x,y) x##y
#define ToChar(a) #@a
#define ToString(x) #x
int main()
{
int a = Conn(1ƺ);
printf("%d\n", a);
printf("%c\n", ToChar(4));
printf(ToString(45678\n));
return 0;
}
輸出結(jié)果為:
12
4
45678
以下是UBOOT中的一部分源代碼:
#define U_BOOT_CMD(name, maxargs, rep, cmd, usage, help)\
cmd_tbl_t u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage}
二、#pragma pack()的使用:
在所有的預(yù)處理指令中,#pragma 指令可能是最復(fù)雜的了,它的作用是設(shè)定編譯器的狀態(tài)或者是指示編譯器完成一些特定的動(dòng)作。#pragma指令對(duì)每個(gè)編譯器給出了一個(gè)方法,在保持與C和C ++語(yǔ)言完全兼容的情況下,給出主機(jī)或操作系統(tǒng)專有的特征。依據(jù)定義,編譯指示是機(jī)器或操作系統(tǒng)專有的,且對(duì)于每個(gè)編譯器都是不同的。
其格式一般為:#pragma para,其中para為參數(shù),下面來(lái)看一些常用的參數(shù)。
#pragma pack規(guī)定的對(duì)齊長(zhǎng)度,什么是對(duì)齊,以及為什么要對(duì)齊:現(xiàn)代計(jì)算機(jī)中內(nèi)存空間都是按照byte劃分的,從理論上講似乎對(duì)任何類型的變量的訪問可以從任何地址開始,但實(shí)際情況是在訪問特定變量的時(shí)候經(jīng)常在特定的內(nèi)存地址訪問,這就需要各類型數(shù)據(jù)按照一定的規(guī)則在空間上排列,而不是順序的一個(gè)接一個(gè)的排放,這就是對(duì)齊。對(duì)齊的作用和原因:各個(gè)硬件平臺(tái)對(duì)存儲(chǔ)空間的處理上有很大的不同。一些平臺(tái)對(duì)某些特定類型的數(shù)據(jù)只能從某些特定地址開始存取。其他平臺(tái)可能沒有這種情況,但是最常見的是如果不按照適合其平臺(tái)要求對(duì)數(shù)據(jù)存放進(jìn)行對(duì)齊,會(huì)在存取效率上帶來(lái)?yè)p失。比如有些平臺(tái)每次讀都是從偶地址開始,如果一個(gè)int型(假設(shè)為32位系統(tǒng))如果存放在偶地址開始的地方,那么一個(gè)讀周期就可以讀出,而如果存放在奇地址開始的地方,就可能會(huì)需要2個(gè)讀周期,并對(duì)兩次讀出的結(jié)果的高低字節(jié)進(jìn)行拼湊才能得到該int數(shù)據(jù)。顯然在讀取效率上下降很多。這也是空間和時(shí)間的博弈。對(duì)齊的實(shí)現(xiàn)通常,我們寫程序的時(shí)候,不需要考慮對(duì)齊問題。編譯器會(huì)替我們選擇時(shí)候目標(biāo)平臺(tái)的對(duì)齊策略。當(dāng)然,我們也可以通知給編譯器傳遞預(yù)編譯指令而改變對(duì)指定數(shù)據(jù)的對(duì)齊方法。但是,正因?yàn)槲覀円话悴恍枰P(guān)心這個(gè)問題,所以因?yàn)榫庉嬈鲗?duì)數(shù)據(jù)存放做了對(duì)齊,而我們不了解的話,常常會(huì)對(duì)一些問題感到迷惑。最常見的就是struct數(shù)據(jù)結(jié)構(gòu)的sizeof結(jié)果,出乎意料。為此,我們需要對(duì)對(duì)齊算法所了解。
作用:指定結(jié)構(gòu)體、聯(lián)合以及類成員的packing alignment;
語(yǔ)法:#pragma pack( [show] | [push | pop] [, identifier], n )
#pragma pack(n)來(lái)設(shè)定變量以n字節(jié)對(duì)齊方式。n字節(jié)對(duì)齊就是說(shuō)變量存放的起始地址的偏移量有兩種情況:第一、如果n大于等于該變量所占用的字節(jié)數(shù),那么偏移量必須滿足默認(rèn)的對(duì)齊方式,第二、如果n小于該變量的類型所占用的字節(jié)數(shù),那么偏移量為n的倍數(shù),不用滿足默認(rèn)的對(duì)齊方式。結(jié)構(gòu)的總大小也有個(gè)約束條件,分下面兩種情況:如果n大于所有成員變量類型所占用的字節(jié)數(shù),那么結(jié)構(gòu)的總大小必須為占用空間最大的變量占用的空間數(shù)的倍數(shù);
#pragma pack(push) //保存對(duì)齊狀態(tài)
#pragma pack(2)//設(shè)定為2字節(jié)對(duì)齊
struct test
{
char a;
int b;
char c;
};
#pragma pack(pop)//恢復(fù)原先的對(duì)齊狀態(tài)
以上結(jié)構(gòu)體的大小為8,下面分析其存儲(chǔ)情況,首先為a分配空間,其偏移量為0,滿足我們自己設(shè)定的對(duì)齊方式(2字節(jié)對(duì)齊),a大小為1個(gè)字節(jié)。接著開始為b分配空間,這時(shí)其偏移量為2,需要補(bǔ)足1個(gè)字節(jié),這樣使偏移量滿足為n=2的倍數(shù)(因?yàn)閟izeof(int)大于4),b占用4個(gè)字節(jié)。接著為c分配空間,這時(shí)其偏移量為6,滿足為2的倍數(shù),c占用1個(gè)字節(jié)。這時(shí)已經(jīng)為所有成員變量分配了空間,共分配了8個(gè)字節(jié),滿足為2的倍數(shù)。如果把上面的#pragma pack(2)改為#pragma pack(4),那么我們可以得到結(jié)構(gòu)的大小為12。
C程序的源代碼中可包括各種編譯指令,這些指令稱為預(yù)處理命令。雖然它們實(shí)際上不是C語(yǔ)言的一部分,但卻擴(kuò)展了C程序設(shè)計(jì)的環(huán)境。本節(jié)將介紹如何應(yīng)用預(yù)處理程序和注釋簡(jiǎn)化程序開發(fā)過(guò)程,并提高程序的可讀性。
一、C宏體中出現(xiàn)的#,#@,##:
1、#的功能是將其后面的宏參數(shù)進(jìn)行字符串化操作(Stringfication)
2、##被稱為連接符(concatenator),用來(lái)將兩個(gè)Token連接為一個(gè)Token。
3、#@的功能是將其后面的宏參數(shù)進(jìn)行字符化。
以下是應(yīng)用的代碼:
#include <stdio.h>
#define Conn(x,y) x##y
#define ToChar(a) #@a
#define ToString(x) #x
int main()
{
int a = Conn(1ƺ);
printf("%d\n", a);
printf("%c\n", ToChar(4));
printf(ToString(45678\n));
return 0;
}
輸出結(jié)果為:
12
4
45678
以下是UBOOT中的一部分源代碼:
#define U_BOOT_CMD(name, maxargs, rep, cmd, usage, help)\
cmd_tbl_t u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage}
二、#pragma pack()的使用:
在所有的預(yù)處理指令中,#pragma 指令可能是最復(fù)雜的了,它的作用是設(shè)定編譯器的狀態(tài)或者是指示編譯器完成一些特定的動(dòng)作。#pragma指令對(duì)每個(gè)編譯器給出了一個(gè)方法,在保持與C和C ++語(yǔ)言完全兼容的情況下,給出主機(jī)或操作系統(tǒng)專有的特征。依據(jù)定義,編譯指示是機(jī)器或操作系統(tǒng)專有的,且對(duì)于每個(gè)編譯器都是不同的。
其格式一般為:#pragma para,其中para為參數(shù),下面來(lái)看一些常用的參數(shù)。
#pragma pack規(guī)定的對(duì)齊長(zhǎng)度,什么是對(duì)齊,以及為什么要對(duì)齊:現(xiàn)代計(jì)算機(jī)中內(nèi)存空間都是按照byte劃分的,從理論上講似乎對(duì)任何類型的變量的訪問可以從任何地址開始,但實(shí)際情況是在訪問特定變量的時(shí)候經(jīng)常在特定的內(nèi)存地址訪問,這就需要各類型數(shù)據(jù)按照一定的規(guī)則在空間上排列,而不是順序的一個(gè)接一個(gè)的排放,這就是對(duì)齊。對(duì)齊的作用和原因:各個(gè)硬件平臺(tái)對(duì)存儲(chǔ)空間的處理上有很大的不同。一些平臺(tái)對(duì)某些特定類型的數(shù)據(jù)只能從某些特定地址開始存取。其他平臺(tái)可能沒有這種情況,但是最常見的是如果不按照適合其平臺(tái)要求對(duì)數(shù)據(jù)存放進(jìn)行對(duì)齊,會(huì)在存取效率上帶來(lái)?yè)p失。比如有些平臺(tái)每次讀都是從偶地址開始,如果一個(gè)int型(假設(shè)為32位系統(tǒng))如果存放在偶地址開始的地方,那么一個(gè)讀周期就可以讀出,而如果存放在奇地址開始的地方,就可能會(huì)需要2個(gè)讀周期,并對(duì)兩次讀出的結(jié)果的高低字節(jié)進(jìn)行拼湊才能得到該int數(shù)據(jù)。顯然在讀取效率上下降很多。這也是空間和時(shí)間的博弈。對(duì)齊的實(shí)現(xiàn)通常,我們寫程序的時(shí)候,不需要考慮對(duì)齊問題。編譯器會(huì)替我們選擇時(shí)候目標(biāo)平臺(tái)的對(duì)齊策略。當(dāng)然,我們也可以通知給編譯器傳遞預(yù)編譯指令而改變對(duì)指定數(shù)據(jù)的對(duì)齊方法。但是,正因?yàn)槲覀円话悴恍枰P(guān)心這個(gè)問題,所以因?yàn)榫庉嬈鲗?duì)數(shù)據(jù)存放做了對(duì)齊,而我們不了解的話,常常會(huì)對(duì)一些問題感到迷惑。最常見的就是struct數(shù)據(jù)結(jié)構(gòu)的sizeof結(jié)果,出乎意料。為此,我們需要對(duì)對(duì)齊算法所了解。
作用:指定結(jié)構(gòu)體、聯(lián)合以及類成員的packing alignment;
語(yǔ)法:#pragma pack( [show] | [push | pop] [, identifier], n )
#pragma pack(n)來(lái)設(shè)定變量以n字節(jié)對(duì)齊方式。n字節(jié)對(duì)齊就是說(shuō)變量存放的起始地址的偏移量有兩種情況:第一、如果n大于等于該變量所占用的字節(jié)數(shù),那么偏移量必須滿足默認(rèn)的對(duì)齊方式,第二、如果n小于該變量的類型所占用的字節(jié)數(shù),那么偏移量為n的倍數(shù),不用滿足默認(rèn)的對(duì)齊方式。結(jié)構(gòu)的總大小也有個(gè)約束條件,分下面兩種情況:如果n大于所有成員變量類型所占用的字節(jié)數(shù),那么結(jié)構(gòu)的總大小必須為占用空間最大的變量占用的空間數(shù)的倍數(shù);
#pragma pack(push) //保存對(duì)齊狀態(tài)
#pragma pack(2)//設(shè)定為2字節(jié)對(duì)齊
struct test
{
char a;
int b;
char c;
};
#pragma pack(pop)//恢復(fù)原先的對(duì)齊狀態(tài)
以上結(jié)構(gòu)體的大小為8,下面分析其存儲(chǔ)情況,首先為a分配空間,其偏移量為0,滿足我們自己設(shè)定的對(duì)齊方式(2字節(jié)對(duì)齊),a大小為1個(gè)字節(jié)。接著開始為b分配空間,這時(shí)其偏移量為2,需要補(bǔ)足1個(gè)字節(jié),這樣使偏移量滿足為n=2的倍數(shù)(因?yàn)閟izeof(int)大于4),b占用4個(gè)字節(jié)。接著為c分配空間,這時(shí)其偏移量為6,滿足為2的倍數(shù),c占用1個(gè)字節(jié)。這時(shí)已經(jīng)為所有成員變量分配了空間,共分配了8個(gè)字節(jié),滿足為2的倍數(shù)。如果把上面的#pragma pack(2)改為#pragma pack(4),那么我們可以得到結(jié)構(gòu)的大小為12。
武漢電腦培訓(xùn)培訓(xùn)相關(guān)新聞
武漢電腦培訓(xùn)相關(guān)課程
- 暑假武漢網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn)班、武漢網(wǎng)頁(yè)設(shè)計(jì)全能班培訓(xùn)、武漢網(wǎng)站優(yōu)化…
- 武漢網(wǎng)頁(yè)設(shè)計(jì)全能班培訓(xùn)、武漢網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn)班、武漢網(wǎng)站優(yōu)化培訓(xùn)…
- 武漢網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn)班、武漢網(wǎng)頁(yè)設(shè)計(jì)全能班培訓(xùn)、武漢網(wǎng)站優(yōu)化培訓(xùn)…
- 武漢網(wǎng)頁(yè)設(shè)計(jì)美工培訓(xùn)、武漢網(wǎng)頁(yè)設(shè)計(jì)師培訓(xùn)、武漢平面設(shè)計(jì)培訓(xùn)、…
- 武漢網(wǎng)頁(yè)短期速成班培訓(xùn)、武漢網(wǎng)站優(yōu)化培訓(xùn)、武漢網(wǎng)頁(yè)全科班、武…
- 武昌武漢辦公基礎(chǔ)培訓(xùn)、武漢辦公精品班培訓(xùn)、武昌辦公文秘培訓(xùn)、…
- 武漢辦公文員培訓(xùn)、武漢計(jì)算機(jī)短期培訓(xùn)、武昌辦公軟件培訓(xùn)學(xué)校、…
- 武漢辦公自動(dòng)化培訓(xùn)學(xué)校、武昌辦公文秘培訓(xùn)、武昌計(jì)算機(jī)基礎(chǔ)培訓(xùn)…
- 武漢高級(jí)辦公文秘培訓(xùn)、武昌高級(jí)商務(wù)文秘班、武昌辦公基礎(chǔ)培訓(xùn)、…
- 武漢計(jì)算機(jī)短期培訓(xùn)、武昌辦公軟件培訓(xùn)學(xué)校、武昌高級(jí)辦公軟件培…
- 武漢平面設(shè)計(jì)短期培訓(xùn)、武漢平面設(shè)計(jì)培訓(xùn)、武漢平面廣告設(shè)計(jì)培訓(xùn)…
- 武漢ps高級(jí)培訓(xùn)班、武漢平面設(shè)計(jì)培訓(xùn)、武漢平面廣告設(shè)計(jì)培訓(xùn)、武…
- 武漢ps短期培訓(xùn)、武昌ps培訓(xùn)、武漢平面設(shè)計(jì)培訓(xùn)、武漢平面廣告設(shè)…
- 武漢平面廣告高級(jí)班、武漢平面設(shè)計(jì)培訓(xùn)、武漢平面廣告設(shè)計(jì)培訓(xùn)、…
武漢電腦培訓(xùn)相關(guān)機(jī)構(gòu)
武漢最新資訊
- 青島雅思—專家談雅思考試發(fā)展趨勢(shì)
- 河南2011上半年自考網(wǎng)上報(bào)名入口 點(diǎn)…
- 2011年廣東省護(hù)士資格考試報(bào)名現(xiàn)場(chǎng)確…
- 2011上半年樂山五通橋區(qū)會(huì)計(jì)從業(yè)考試…
- 哈爾濱香坊區(qū)2011護(hù)士資格考試報(bào)名現(xiàn)…
- 2011什邡第一次會(huì)計(jì)從業(yè)資格考試報(bào)名…
- 2011什邡第二次會(huì)計(jì)從業(yè)資格考試報(bào)名…
- 2011年中山市護(hù)士資格考試報(bào)名工作的…
- 長(zhǎng)安大學(xué)2011考研成績(jī)查詢?nèi)肟?點(diǎn)擊…
- 西華大學(xué)2011考研成績(jī)查詢?nèi)肟?點(diǎn)擊…
武漢推薦課程導(dǎo)航
雅思 | 口語(yǔ) | 日語(yǔ) | 韓語(yǔ) | 德語(yǔ) | 四六級(jí) | 商務(wù)英語(yǔ) | 平面設(shè)計(jì) | 游戲動(dòng)漫 | 影視制作 | 室內(nèi)外設(shè)計(jì) | 動(dòng)畫設(shè)計(jì) | 網(wǎng)頁(yè)設(shè)計(jì) | 等級(jí)考試軟件工程 | 美容培訓(xùn) | 手機(jī)維修 | 廚師面點(diǎn) | 會(huì)計(jì)職稱 | 心理咨詢 | 人力資源