女人被狂躁到高潮视频免费无遮挡,内射人妻骚骚骚,免费人成小说在线观看网站,九九影院午夜理论片少妇,免费av永久免费网址

當(dāng)前位置:首頁(yè) > > 充電吧
[導(dǎo)讀]現(xiàn)在的一些處理器,需要你的數(shù)據(jù)的內(nèi)存地址必須是對(duì)齊(align)的,即使不是必須,如果你對(duì)齊的話,運(yùn)行的速度也會(huì)得到提升。雖然對(duì)齊會(huì)產(chǎn)生的額外內(nèi)存空間,但相對(duì)于這個(gè)速度的提升來(lái)說(shuō),是值得的。 所謂對(duì)

現(xiàn)在的一些處理器,需要你的數(shù)據(jù)的內(nèi)存地址必須是對(duì)齊(align)的,即使不是必須,如果你對(duì)齊的話,運(yùn)行的速度也會(huì)得到提升。雖然對(duì)齊會(huì)產(chǎn)生的額外內(nèi)存空間,但相對(duì)于這個(gè)速度的提升來(lái)說(shuō),是值得的。

所謂對(duì)齊,就是地址必須能整除一個(gè)整數(shù),這個(gè)就是對(duì)齊參數(shù)(alignment value)。合法的取值范圍是1、2、4、6、16、……、8192。

怎樣對(duì)齊呢?編譯器幫你搞定。

怎樣設(shè)置編譯器的對(duì)齊方式呢?用#pragma pack( n )和__declspec(align(#))。

依據(jù)它倆,編譯器是咋工作的?這個(gè)就是接下來(lái)要說(shuō)的了。

#include?
#pragma?pack(?1?)
struct?A
{?????????????
????char?a;
????short?b;
????char?c;
};

int?main()
{
????printf("%dn",sizeof(A));
????return?0;
}
?

OK,下面對(duì)這個(gè)代碼進(jìn)行詳細(xì)的分析。

?

用MSDN的話一言以蔽之:

“The alignment of a member (except the first one) will be on a boundary that is either a multiple of n or a multiple of the size of the member, whichever is smaller.”

翻譯成中文,也就是:

“結(jié)構(gòu)體中的數(shù)據(jù)成員,除了第一個(gè)是始終放在最開(kāi)始的地方,其它數(shù)據(jù)成員的地址必須是它本身大小或?qū)R參數(shù)兩者中較小的一個(gè)的倍數(shù)?!?/p>

?

P.S:注意上面所說(shuō)的后面一句話,也就是說(shuō),結(jié)構(gòu)體的數(shù)據(jù)成員的地址必須是本身大小和對(duì)齊參數(shù)中較小的那一個(gè)。

?

?

(1)在pack為1的時(shí)候,對(duì)齊參數(shù)是1,那么我們對(duì)這個(gè)結(jié)構(gòu)體每一元素進(jìn)行分析。

?

char a;??????? //??? 第一個(gè)元素在[0]位置處

?short b;?//short兩個(gè)字節(jié),地址是min(1,sizeof(short))的倍數(shù),即1的倍數(shù)[1~2]

?char c; // 地址應(yīng)該是min(1,sizeof(1))的倍數(shù),從而即為[3]

?

故在pack為1的時(shí)候,輸出的結(jié)果應(yīng)該是4([0~3]),其中所有的元素都填滿了。

?

?

(2)在pack為2的時(shí)候,同樣按照上面的方法,我們繼續(xù)來(lái)分析下。

Char a; //第一個(gè)占[0]位置。

Short b; //min(2,sizeof(short)),也就是必須為2的倍數(shù),從而[2~3]

Char c;//min(2,sizeof(char)),也就是位1,地址為[4]

因此最后占據(jù)的大小是[0],[2~3],[4],整個(gè)結(jié)構(gòu)體的大小size必須是2的倍數(shù),所以應(yīng)該是6(向上對(duì)齊至2的倍數(shù))

?

?

(3)在pack為4的時(shí)候,同上,得到的結(jié)果是

[0],[2~3],[4],因此也是6.

?

?

然后我們對(duì)上面的這個(gè)結(jié)構(gòu)體變換一下順序,可以得到。

?

struct B

{

???????? char a;

???????? char b;

???????? short c;

};

?

?

在#pragma pack(4)的情況下,輸出卻是4(注:上面的輸出時(shí)6)

解釋如下:

?

Char a;//占據(jù)一個(gè)字節(jié),地址為【0】

Char b;//地址應(yīng)該是min(4,sizeof(char)) = 1的倍數(shù),也就是地址為【1】

Short c; //地址應(yīng)該是min(4,sizeof(short)) = 2的倍數(shù),也就是【2~3】

故總體占據(jù)的是【0~3】的連續(xù)單元,也就是4.

?

?

至此,我們對(duì)#prgama pack(n)的用法和對(duì)應(yīng)的判定方法有了一個(gè)全新的認(rèn)識(shí)。



?

特別提出:
sizeof(ao.a )還是1,sizeof(ao.b )還是2。

?如果struct B中含有A的一個(gè)對(duì)象m_a,
struct B
{
???…
???A m_a;
???…
}
則這個(gè)m_a對(duì)齊參數(shù)是A中最大的數(shù)據(jù)類型的大?。ㄟ@里是short的2)和n中較小者。如果這個(gè)對(duì)齊參數(shù)是B中最大的話,最后B的大小也會(huì)與這個(gè)對(duì)齊參數(shù)有關(guān)。


m_a的對(duì)齊參數(shù),由于是A的變量,所以采用A的對(duì)齊參數(shù),也就是應(yīng)該是A的最大元素個(gè)數(shù)和n中較小的值。而B的大小就要根據(jù)這個(gè)對(duì)齊參數(shù)來(lái)確定大小。


#include?
#include?

#define?NUM?1
using?namespace?std;

#pragma?pack?(?16?)

typedef?struct?{
????int?a;
????char?b;
????double?c;
}test;

struct?B
{
????int?a;
????test?b;
};
int?main()
{
????cout?< ????cout?< ????cout?< ????cout?< ????cout?< ????system("PAUSE");
????return?0;
}

?

(1)在pack為1的時(shí)候,由于min中有一個(gè)為1,所以都是相鄰存放的。

Sizeof(test)就是int+char+double的大小之和,即13.

而對(duì)應(yīng)的sizeof(B)則是一個(gè)int和一個(gè)struct之和。Int占4B,而struct的對(duì)齊參數(shù)則是

Min(1,sizeof(max(A)),A中最大的元素師double類型的,也就是8,所以結(jié)果是min(1,8)=1,所以也是相鄰存放的,而sizeof(A)的結(jié)果是13,所以直接是13+4 = 17.

此時(shí),sizeof(B)的大小是17.

?

(2)?在pack為2的時(shí)候,此時(shí)min中有一個(gè)為2,對(duì)于test結(jié)構(gòu)體,它的大小是4+2+8=14,因?yàn)樵赿ouble的時(shí)候,min(2,8)=2,所以double類型的變量應(yīng)該是2的倍數(shù)的地址,造成了char類型處空出了一個(gè)字節(jié)。總體就是14B。而對(duì)于B結(jié)構(gòu)體而言,一個(gè)int占據(jù)4B,然后結(jié)構(gòu)體的對(duì)齊參數(shù)采用min(2,max(A)),即min(2,8)= 2,由于是int,所以下一個(gè)地址是4,自然也是2的倍數(shù),于是還是相鄰存放。而A結(jié)構(gòu)體的大小時(shí)14,于是B結(jié)構(gòu)體的大小時(shí)14+4=18.

(3)?在pack為4的情況下。同樣可以得到。此時(shí)對(duì)于A結(jié)構(gòu)體的大小是4+4+8=16,因?yàn)閐ouble類型的必須是4的倍數(shù),造成了char變量要占4個(gè)地方(實(shí)際只占一個(gè),只是說(shuō)這個(gè)地方空出來(lái)了3B),所以總體的大小為16.而同樣對(duì)于B結(jié)構(gòu)體,sizeof的結(jié)果是16+4 = 20,因?yàn)閷?duì)于里面的成員要是min(4,8) = 4,而int恰好是4的倍數(shù),所以相鄰存放。于是就是16,20.

(4)?在pack為8的情況下(有所變化?。。。?,此時(shí)A結(jié)構(gòu)體的大小是16,分析方法和上面相同,但是對(duì)于結(jié)構(gòu)體B而言就有所區(qū)別,此時(shí)int還是4個(gè)字節(jié),但是對(duì)于成員test結(jié)構(gòu)體,它的對(duì)齊參數(shù)是min(8,max(A)) = min(8,sizeof(double) ) = 8也就是對(duì)齊參數(shù)是8,所以結(jié)構(gòu)體變量要從地址為8開(kāi)始,此時(shí)int就空出來(lái)了4B,從而最后求大小的時(shí)候應(yīng)該是8+sizeof(A)= 8+16=24(最終測(cè)試結(jié)果如此)

(5)在pack為16的情況(以及以后的情況),結(jié)果是:A的大小為16B,而B的大小是24B。

?

?

總結(jié):

(1)?????? 對(duì)于一個(gè)由簡(jiǎn)單類型組成的結(jié)構(gòu)體,它的大小是由每一個(gè)成員變量的地址決定的。我們要按照定義的順序,分別求出來(lái)地址開(kāi)始的地方。從地址為0開(kāi)始,每一個(gè)變量都采取min(n,sizeof(x))//x表示該變量的類型;來(lái)確定起始地址是多少的倍數(shù),然后開(kāi)始計(jì)數(shù),直到填滿該數(shù)據(jù)。最后求出來(lái)總的大小。而且在pack>=2的時(shí)候最終的大小需要時(shí)2的倍數(shù),有時(shí)候需要向上取大為2的倍數(shù)。而在pack為1的情況則不需要。

(2)?????? 對(duì)于含有結(jié)構(gòu)體成員的結(jié)構(gòu)體,方法同上,只是在于對(duì)于結(jié)構(gòu)體變量的對(duì)齊參數(shù)取法需要說(shuō)明,具體就是min(n,結(jié)構(gòu)體成員的最大元素的大小),就像上面的,結(jié)構(gòu)體B中含有A成員,所以對(duì)齊參數(shù)就是min(n,sizeof(double))的大小,然后按照這個(gè)做法來(lái)取地址。


P.S:注意這里是pack而不是package,否則編譯器會(huì)直接忽略#pragma package(),因?yàn)榧词拱l(fā)生錯(cuò)誤編譯器也會(huì)直接忽略,而我們還是會(huì)默認(rèn)認(rèn)為編譯器已經(jīng)當(dāng)做了字節(jié)按照n來(lái)處理。(某些博客上面的內(nèi)容很容易讓人誤解或者暈倒!)

以上代碼結(jié)果在Dev C++ , C-Free 5.0,VS 2010上均通過(guò)測(cè)試。



附注:在默認(rèn)情況下,linux操作系統(tǒng)是以4字節(jié)對(duì)齊,windows操作系統(tǒng)則是以最大的內(nèi)置類型對(duì)齊。

作用:指定結(jié)構(gòu)體、聯(lián)合以及類成員的packing alignment;
語(yǔ)法:#pragma pack( [show] | [push | pop] [, identifier], n )
說(shuō)明:
1,pack提供數(shù)據(jù)聲明級(jí)別的控制,對(duì)定義不起作用;
2,調(diào)用pack時(shí)不指定參數(shù),n將被設(shè)成默認(rèn)值;
3,一旦改變數(shù)據(jù)類型的alignment,直接效果就是占用memory的減少,但是performance會(huì)下降。
語(yǔ)法具體分析:
1,show:可選參數(shù);顯示當(dāng)前packing aligment的字節(jié)數(shù),以warning message的形式被顯示;
2,push:可選參數(shù);將當(dāng)前指定的packing alignment數(shù)值進(jìn)行壓棧操作,這里的棧是the internal compiler stack,同時(shí)設(shè)置當(dāng)前的packing alignment為n;如果n沒(méi)有指定,則將當(dāng)前的packing alignment數(shù)值壓棧;
3,pop:可選參數(shù);從internal compiler stack中刪除最頂端的record;如果沒(méi)有指定n,則當(dāng)前棧頂record即為新的packing alignment數(shù)值;如果指定了n,則n將成為新的packing aligment數(shù)值;如果指定了identifier,則internal compiler stack中的record都將被pop直到identifier被找到,然后pop出identitier,同時(shí)設(shè)置packing alignment數(shù)值為當(dāng)前棧頂?shù)膔ecord;如果指定的identifier并不存在于internal compiler stack,則pop操作被忽略;
4,identifier:可選參數(shù);當(dāng)同push一起使用時(shí),賦予當(dāng)前被壓入棧中的record一個(gè)名稱;當(dāng)同pop一起使用時(shí),從internal compiler stack中pop出所有的record直到identifier被pop出,如果identifier沒(méi)有被找到,則忽略pop操作;
5,n:可選參數(shù);指定packing的數(shù)值,以字節(jié)為單位;缺省數(shù)值是8,合法的數(shù)值分別是1、2、4、8、16。


#include


int main()
{
struct B{
char b; ? //對(duì)其系數(shù)1
int a; ? ? ?//對(duì)其系數(shù)4
short c; ?//對(duì)其系數(shù)2
};//整體對(duì)其系數(shù)4
/*
struct A{
char b; ? //對(duì)其系數(shù)1
int a; ? ? ?//對(duì)其系數(shù)4
struct B f;
short c; ?//對(duì)其系數(shù)2
};//整體對(duì)其系數(shù)4*/
#pragma pack(push) //保存對(duì)齊狀態(tài)
#pragma pack (2)//無(wú)法識(shí)別的預(yù)處理命令


struct person{
/*char dda;
double dda1;
int type;
*/
char b;//整體對(duì)其系數(shù)1
double c; //整體對(duì)其系數(shù)8
char age;//整體對(duì)其系數(shù)1


};//整體對(duì)其系數(shù)8
#pragma pack(pop)//恢復(fù)對(duì)齊狀態(tài)
struct room{
char chair[5];//整體對(duì)其系數(shù)1
int computer;//整體對(duì)其系數(shù)1
struct person children;//整體對(duì)其系數(shù)8
};
int size_r = sizeof(struct room);
int size_p = sizeof(struct person);
printf("size_r = %dnsize_p = %d", size_r,size_p);
getchar();?
}


本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動(dòng)電源

在工業(yè)自動(dòng)化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動(dòng)力設(shè)備,其驅(qū)動(dòng)電源的性能直接關(guān)系到整個(gè)系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動(dòng)勢(shì)抑制與過(guò)流保護(hù)是驅(qū)動(dòng)電源設(shè)計(jì)中至關(guān)重要的兩個(gè)環(huán)節(jié),集成化方案的設(shè)計(jì)成為提升電機(jī)驅(qū)動(dòng)性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動(dòng)電源

LED 驅(qū)動(dòng)電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個(gè)照明設(shè)備的使用壽命。然而,在實(shí)際應(yīng)用中,LED 驅(qū)動(dòng)電源易損壞的問(wèn)題卻十分常見(jiàn),不僅增加了維護(hù)成本,還影響了用戶體驗(yàn)。要解決這一問(wèn)題,需從設(shè)計(jì)、生...

關(guān)鍵字: 驅(qū)動(dòng)電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動(dòng)電源的公式,電感內(nèi)電流波動(dòng)大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計(jì) 驅(qū)動(dòng)電源

電動(dòng)汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動(dòng)汽車的核心技術(shù)之一是電機(jī)驅(qū)動(dòng)控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動(dòng)系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動(dòng)汽車的動(dòng)力性能和...

關(guān)鍵字: 電動(dòng)汽車 新能源 驅(qū)動(dòng)電源

在現(xiàn)代城市建設(shè)中,街道及停車場(chǎng)照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨(dú)特的優(yōu)勢(shì)逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動(dòng)電源 LED

LED通用照明設(shè)計(jì)工程師會(huì)遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動(dòng)電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動(dòng)電源的電磁干擾(EMI)問(wèn)題成為了一個(gè)不可忽視的挑戰(zhàn)。電磁干擾不僅會(huì)影響LED燈具的正常工作,還可能對(duì)周圍電子設(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來(lái)解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動(dòng)電源

開(kāi)關(guān)電源具有效率高的特性,而且開(kāi)關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動(dòng)電源

關(guān)鍵字: LED 驅(qū)動(dòng)電源 開(kāi)關(guān)電源

LED驅(qū)動(dòng)電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動(dòng)LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動(dòng)電源
關(guān)閉