關(guān)于結(jié)構(gòu)體數(shù)據(jù)存儲(chǔ)的對(duì)齊問題
首先應(yīng)該明白基本的類型在內(nèi)存中的大小,char型一般占有1個(gè)字節(jié),int型一般占有4個(gè)字節(jié),double型一般占有8個(gè)字節(jié),short 則占有2個(gè)字節(jié)(當(dāng)然也會(huì)存在一定的變化,具體情況依據(jù)編譯器決定)。我們都知道C語言的結(jié)構(gòu)體是一個(gè)不同類型數(shù)據(jù)的集合。那么一個(gè)結(jié)構(gòu)體到底占多少存儲(chǔ)空間呢?
首先應(yīng)該意識(shí)到C語言的存儲(chǔ)存在一定的特殊性。在C語言的結(jié)構(gòu)體中需要主要的是數(shù)據(jù)存儲(chǔ)的對(duì)齊方式。對(duì)齊主要是為了方便數(shù)據(jù)的訪問,提高計(jì)算機(jī)的處理速度,但是對(duì)齊會(huì)導(dǎo)致內(nèi)存空間的浪費(fèi),這些浪費(fèi)對(duì)于大內(nèi)存空間的設(shè)備而言,沒什么必要,但是對(duì)于嵌入式系統(tǒng)而言會(huì)造成大量的浪費(fèi)。
在32bits的系統(tǒng)中對(duì)一個(gè)寄存器(32bits)的訪問直接訪問,但是對(duì)于寄存器中某一個(gè)字節(jié)的訪問反而覺得很不方便,因此如果只是單個(gè)字節(jié)的訪問反而增加了系統(tǒng)的負(fù)擔(dān)。對(duì)一個(gè)寄存器的訪問可以通過一個(gè)起始地址來實(shí)現(xiàn),但是我們?cè)诤芏郈PU的用戶手冊(cè)中都會(huì)發(fā)現(xiàn),寄存器的起始地址都能被4整除,這就是為了提高計(jì)算速度而采取的一些默認(rèn)的方式。一個(gè)寄存器一般而言占有4個(gè)bytes,那么對(duì)下一個(gè)寄存器的訪問只需要在原來的地址基礎(chǔ)上加上4個(gè) bytes即可。
對(duì)齊的基本作用就是提高系統(tǒng)的功能,特別是訪問存儲(chǔ)器的能力得到提高。
對(duì)齊在使用中有較多的意義?;镜氖褂迷瓌t:
1、對(duì)齊是為了提高系統(tǒng)的訪問速度,一般基本的對(duì)齊原則是按著最大的基本類型的長(zhǎng)度進(jìn)行對(duì)齊,較小的元素可以幾個(gè)組合起來填充一段對(duì)齊內(nèi)存,實(shí)現(xiàn)基本的對(duì)齊,但是需要滿足條件2。
2、結(jié)構(gòu)體中的元素也要滿足一定的分布條件,就是元素的存儲(chǔ)起始地址要滿足能夠整除該元素類型的長(zhǎng)度。
3、在結(jié)構(gòu)體中存在結(jié)構(gòu)體的情況下,也只是按著結(jié)構(gòu)體中最大的基本類型長(zhǎng)度對(duì)齊(包含內(nèi)部結(jié)構(gòu)體中的最大基本類型長(zhǎng)度)。
在不同的編譯器之間也存在一定的差別。在linux中最大的對(duì)齊長(zhǎng)度是 4個(gè)字節(jié),也就是如果結(jié)構(gòu)體中的最大的基本類型長(zhǎng)度是大于4的,那么也按著4對(duì)齊,同時(shí)不會(huì)按著結(jié)構(gòu)體中最大的基本類型的長(zhǎng)度對(duì)齊,伴隨著最大基本類型元素的起始地址也不再滿足能夠被最大元素類型長(zhǎng)度對(duì)齊的原則,而是滿足整除4即可。但如果結(jié)構(gòu)體中最大的基本類型長(zhǎng)度小于4,那么按著最大的基本類型長(zhǎng)度對(duì)齊
但是在windows中基本上都是按著最大的基本類型長(zhǎng)度進(jìn)行對(duì)齊,和一般的原則相似。
這邊只是我的一些理解其中具體的要具體分析,在實(shí)際中建議將最大基本類型的元素放在開始的地方,然后將其他的數(shù)據(jù)按著一定的規(guī)律(能否組合起來滿足對(duì)齊條件等)定義結(jié)構(gòu)體,這個(gè)規(guī)律要根據(jù)實(shí)際情況分析。
下面通過基本的代碼進(jìn)行演示:
- #include
- #include
- struct aa{
- char a;
- double b;
- short c;
- };
- struct bb
- {
- doublea;
- short b;
- char c;
- };
- struct cc
- {
- struct bb s1;
- char s2;
- };
- struct dd
- {
- struct aa s1;
- char s2;
- };
- #pragma pack(1)
- struct ee
- {
- double a;
- short b;
- char c;
- };
- struct ff
- {
- char a;
- double b;
- short c;
- };
- #pragmapack()
- struct gg
- {
- char a;
- };
- struct jj
- {
- char a;
- short b;
- };
- intmain()
- {
- printf("doublesize is %d %d %d",sizeof(double),sizeof(short),sizeof(char));
- printf("size of s1 = %dsize of s2 = %d",sizeof(struct aa),sizeof(struct bb));
- printf("size of t1 = %dsize of dd = %d",sizeof(struct cc),sizeof(struct dd));
- printf("size of struct ee = %dsize of struct ff = %dsize of struct gg = %dsize of struct jj = %d",
- sizeof(struct ee),sizeof(struct ff),sizeof(struct gg),sizeof(struct jj));
- exit(0);
- }
關(guān)鍵詞:
結(jié)構(gòu)體數(shù)據(jù)存儲(chǔ)對(duì)齊問
相關(guān)推薦
技術(shù)專區(qū)
- FPGA
- DSP
- MCU
- 示波器
- 步進(jìn)電機(jī)
- Zigbee
- LabVIEW
- Arduino
- RFID
- NFC
- STM32
- Protel
- GPS
- MSP430
- Multisim
- 濾波器
- CAN總線
- 開關(guān)電源
- 單片機(jī)
- PCB
- USB
- ARM
- CPLD
- 連接器
- MEMS
- CMOS
- MIPS
- EMC
- EDA
- ROM
- 陀螺儀
- VHDL
- 比較器
- Verilog
- 穩(wěn)壓電源
- RAM
- AVR
- 傳感器
- 可控硅
- IGBT
- 嵌入式開發(fā)
- 逆變器
- Quartus
- RS-232
- Cyclone
- 電位器
- 電機(jī)控制
- 藍(lán)牙
- PLC
- PWM
- 汽車電子
- 轉(zhuǎn)換器
- 電源管理
- 信號(hào)放大器
評(píng)論