上面主要考點在於c語言的sizeof 以及 c語言中的對齊的概念。其中主要的思想是讀取資料的時候通過空間換取時間的策略。
1. 什麼是位元組對齊?
在c語言中,結構是一種復合資料型別,其構成元素既可以是基本資料型別(如int、long、float等)的變數,也可以是一些復合資料型別(如陣列、結構、聯合等)的資料單元。在結構中,編譯器為結構的每個成員按其自然邊界(alignment)分配空間。各個成員按照它們被宣告的順序在記憶體中順序儲存,第乙個成員的位址和整個結構的位址相同。
為了使cpu能夠對變數進行快速的訪問,變數的起始位址應該具有某些特性,即所謂的」對齊」. 比如4位元組的int型,其起始位址應該位於4位元組的邊界上,即起始位址能夠被4整除.
2. 位元組對齊有什麼作用?
位元組對齊的作用不僅是便於cpu快速訪問,同時合理的利用位元組對齊可以有效地節省儲存空間。
對於32位機來說,4位元組對齊能夠使cpu訪問速度提高,比如說乙個long型別的變數,如果跨越了4位元組邊界儲存,那麼cpu要讀取兩次,這樣效率就低了。但是在32位機中使用1位元組或者2位元組對齊,反而會使變數訪問速度降低。所以這要考慮處理器型別,另外還得考慮編譯器的型別。在vc中預設是4位元組對齊的,gnu gcc 也是預設4位元組對齊。
深入理解
什麼是位元組對齊,為什麼要對齊?
tragicjun 發表於 2006-9-18 9:41:00 現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定型別變數的時候經常在特定的記憶體位址訪問,這就需要各種型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是對齊。
對齊的作用和原因:各個硬體平台對儲存空間的處理上有很大的不同。一些平台對某些特定型別的資料只能從某些特定位址開始訪問。比如有些架構的cpu在訪問乙個沒有進行對齊的變數的時候會發生錯誤,那麼在這種架構下程式設計必須保證位元組對齊.其他平台可能沒有這種情況,但是最常見的是如果不按照適合其平台要求對資料存放進行對齊,會在訪問效率上帶來損失。比如有些平台每次讀都是從偶位址開始,如果乙個int型(假設為32位系統)如果存放在偶位址開始的地方,那麼乙個讀週期就可以讀出這32bit,而如果存放在奇位址開始的地方,就需要2個讀週期,並對兩次讀出的結果的高低位元組進行拼湊才能得到該32bit資料。顯然在讀取效率上下降很多。
位元組對齊可能帶來的隱患:
**中關於對齊的隱患,很多是隱式的。比如在強制型別轉換的時候。例如:
unsigned int i = 0x12345678;
unsigned char *p=null;
unsigned short *p1=null;
p=&i;
*p=0x00;
p1=(unsigned short *)(p+1);
*p1=0x0000;
最後兩句**,從奇數邊界去訪問unsignedshort型變數,顯然不符合對齊的規定。
在x86上,類似的操作只會影響效率,但是在mips或者sparc上,可能就是乙個error,因為它們要求必須位元組對齊.
最後 部分類容摘取自:
C語言 位元組對齊(記憶體對齊)
1 平台原因 移植原因 不是所有的硬體平台都能訪問任意位址上的任意資料,某些硬體平台只能在某些位址處取某些特定型別的資料,否則丟擲硬體異常 2 硬體原因 經過記憶體對齊之後,cpu的記憶體訪問速度大大提公升。1.對齊原則 原則1 資料成員對齊規則 結構 struct 或聯合 union 的資料成員,...
C語言 記憶體對齊
寫出乙個struct,然後sizeof,你會不會經常對結果感到奇怪?sizeof的結果往往都比你宣告的變數總長度要大,這是怎麼回事呢?講講位元組對齊吧.分割線 如果體系結構是不對齊的,a中的成員將會乙個挨乙個儲存,從而sizeof a 為11。顯然對齊更浪費了空間。那麼為什麼要使用對齊呢?體 繫結構...
c語言位元組對齊
現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定型別變數的時候經常在特 定的記憶體位址訪問,這就需要各種型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是對齊。基本資料型別自身對齊,也叫自然對齊。就是說...