1. 程式人生 > >#pragma pack 對齊方式

#pragma pack 對齊方式

程式編譯器對結構的儲存的特殊處理確實提高CPU儲存變數的速度,但是有時候也帶來了一些麻煩,我們也遮蔽掉變數預設的對齊方式,自己可以設定變數的對齊方式。編譯器中提供了#pragma pack(n)來設定變數以n位元組對齊方式。n位元組對齊就是說變數存放的起始地址的偏移量有兩種情況:第一、如果n大於等於該變數所佔用的位元組數,那麼偏移量必須滿足預設的對齊方式,第二、如果n小於該變數的型別所佔用的位元組數,那麼偏移量為n的倍數,不用滿足預設的對齊方式。結構的總大小也有個約束條件,分下面兩種情況:如果n大於所有成員變數型別所佔用的位元組數,那麼結構的總大小必須為佔用空間最大的變數佔用的空間數的倍數;否則必須為n的倍數。下面舉例說明其用法。#pragma
pack(push) //儲存對齊狀態#pragma pack(4)//設定為4位元組對齊struct test{char m1;double m4;int m3;};#pragma pack(pop)//恢復對齊狀態以上結構體的大小為16,下面分析其儲存情況,首先為m1分配空間,其偏移量為0,滿足我們自己設定的對齊方式(4位元組對齊),m1大小為1個位元組。接著開始為m4分配空間,這時其偏移量為1,需要補足3個位元組,這樣使偏移量滿足為n=4的倍數(因為sizeof(double)大於4),m4佔用8個位元組。接著為m3分配空間,這時其偏移量為12,滿足為4的倍數,m3佔用4個位元組。這時已經為所有成員變數
分配了空間,共分配了16個位元組,滿足為n的倍數。如果把上面的#pragma pack(4)改為#pragma pack(8),那麼我們可以得到結構的大小為24

細說#pragma pack(n)  在C語言中,結構是一種複合資料型別,其構成元素既可以是基本資料型別(如int、long、float等)的變數,也可以是一些複合資料型別(如陣列、結構、聯合等)的資料單元。在結構中,編譯器為結構的每個成員按其自然對界(alignment)條件分配空間。(所謂自然對界條件是指有些CPU要求資料存放的時候要對齊,就是起始地址必須是所佔位元組數的整數倍。RISC   CPU就有這種要求。如果在PowerPC的系統上用這樣一個結構:    struct s {  Char a;  long b;  };      在記憶體裡就會看到:(字母表示這個位元組屬於誰) a   0   0   0    b   b   b   b     由於b需要對齊,所以a和b之間就有了一個3位元組的pad。要是取sizeof(struct   s),就會看到是8。這種對齊在RISC   CPU上是必須的,否則會出錯.      在x86上面則沒有這種必須對齊的要求,a和b之間可以不需要pad。但是你並不能確定他們之間到底有沒有這個pad,這個和編譯器有關係。因為資料對齊的時候訪問效率最高,所以有的編譯器進行了優化,就是在x86上資料照樣也是對齊的。比如gcc,用gcc得到的sizeof(struct   s)就是8,但是如果用Turbo   C,就會看到是5。 “自然對界條件”對齊條件,不是說變數的起始地址必須是其所佔位元組數的整數倍   !    注意這裡的起始地址   是相對地址   !   從   0   開始計算的   ~)  各個成員按照它們被宣告的順序在記憶體中順序儲存,第一個成員的地址和整個結構的地址相同。 例如,下面的結構各成員空間分配情況: struct test  {       char x1;      short x2;      float x3;      char x4; };  結構的第一個成員x1,其偏移地址為0,佔據了第1個位元組。第二個成員x2為short型別,其起始地址必須2位元組對界,因此,編譯器在x2和x1之間填充了一個空位元組。結構的第三個成員x3和第四個成員x4恰好落在其自然對界地址上,在它們前面不需要額外的填充位元組。在test結構中,成員x3要求4位元組對界,是該結構所有成員中要求的最大對界單元,因而test結構的自然對界條件為4位元組,編譯器在成員x4後面填充了3個空位元組。整個結構所佔據空間為12位元組。 更改C編譯器的預設位元組對齊方式  在預設情況下,C編譯器為每一個變數或是資料單元按其自然對界條件分配空間。一般地,可以通過下面的方法來改變預設的對界條件:

· 使用偽指令#pragma pack (n),C編譯器將按照n個位元組對齊。      · 使用偽指令#pragma pack (),取消自定義位元組對齊方式。 另外,還有如下的一種方式:       · __attribute((aligned (n))),讓所作用的結構成員對齊在n位元組自然邊界上。如果結構中有成員的長度大於n,則按照最大成員的長度來對齊。       · __attribute__ ((packed)),取消結構在編譯過程中的優化對齊,按照實際佔用位元組數進行對齊。 以上的n = 1, 2, 4, 8, 16... 第一種方式較為常見。 下面有一道在 CSDN論壇 上討論火熱的題:  Intel和微軟和本公司同時出現的面試題 #pragma pack(8) struct s1{ short a; long b; }; struct s2{ char c; s1 d; long long e; };  #pragma pack() 問   1.sizeof(s2) = ?  2.s2的c後面空了幾個位元組接著是d?  感謝 redleaves(ID最吊的網友) 的解答,結果如下: sizeof(S2)結果為24.  成員對齊有一個重要的條件,即每個成員分別對齊.即每個成員按自己的方式對齊.  也就是說上面雖然指定了按8位元組對齊,但並不是所有的成員都是以8位元組對齊.其對齊的規則是,每個成員按其型別的對齊引數(通常是這個型別的大小)和指定對齊引數(這裡是8位元組)中較小的一個對齊.並且結構的長度必須為所用過的所有對齊引數的整數倍,不夠就補空位元組.  S1中,成員a是1位元組預設按1位元組對齊,指定對齊引數為8,這兩個值中取1,a按1位元組對齊;成員b是4個位元組,預設是按4位元組對齊,這時就按4位元組對齊,所以sizeof(S1)應該為8;  S2中,c和S1中的a一樣,按1位元組對齊,而d 是個結構,它是8個位元組,它按什麼對齊呢?對於結構來說,它的預設對齊方式就是它的所有成員使用的對齊引數中最大的一個,S1的就是4.所以,成員d就是按4位元組對齊.成員e是8個位元組,它是預設按8位元組對齊,和指定的一樣,所以它對到8位元組的邊界上,這時,已經使用了12個位元組了,所以又添加了4個位元組的空,從第16個位元組開始放置成員e.這時,長度為24,已經可以被8(成員e按8位元組對齊)整除.這樣,一共使用了24個位元組.                           a    b S1的記憶體佈局:11**,1111,                            c    S1.a S1.b     d S2的記憶體佈局:1***,11**,1111,****11111111 這裡有三點很重要:  1.每個成員分別按自己的方式對齊,並能最小化長度  2.複雜型別(如結構)的預設對齊方式是它最長的成員的對齊方式,這樣在成員是複雜型別時,可以最小化長度 3.對齊後的長度必須是成員中最大的對齊引數的整數倍,這樣在處理陣列時可以保證每一項都邊界對齊 補充一下,對於陣列,比如:  char a[3];這種,它的對齊方式和分別寫3個char是一樣的.也就是說它還是按1個位元組對齊. 如果寫: typedef char Array3[3];  Array3這種型別的對齊方式還是按1個位元組對齊,而不是按它的長度. 不論型別是什麼,對齊的邊界一定是1,2,4,8,16,32,64....中的一個. 測試的編譯器:  GCC 2.95 3.1 3.3 3.4 4.0 MS C/C++ 7.0 7.1 8.0 beta Borland C/C++ 5.6 6.0 Intel C/C++ 7.0 8.0 8.1 DigitalMars C/C++ 8.4 OpenWatcom 1.3 Codeplay C/C++ 2.1.7   

相關推薦

#pragma pack 方式

程式編譯器對結構的儲存的特殊處理確實提高CPU儲存變數的速度,但是有時候也帶來了一些麻煩,我們也遮蔽掉變數預設的對齊方式,自己可以設定變數的對齊方式。編譯器中提供了#pragma pack(n)來設定變數以n位元組對齊方式。n位元組對齊就是說變數存放的起始地址的偏移量有兩種情

pragma pack方式詳細介紹

為了加快讀寫資料的速度,編譯器採用資料對齊的方式來為每一個結構體分配空間。——寫在開頭 本文有自己的原創也有轉載的博文,轉載的部分一一列出來,可能不全請見諒這裡這裡這裡這裡等等。。。。。。 (更詳細的解說:        在用sizeof運算子求算某結構體所佔空間時,並不

pragma pack 用法

      為了搞清楚#pragma pack(n)的寫法,Test一下。下面這段測試程式碼貼在任意一個控制檯程式的面前面即可。 //windowsxp+vs2008 //#pragma pack(sh

C語言中的方式#pragma pack()偽指令及_attribute_aligned_指令

Q:為什麼會引入這樣的偽指令呢? A:我們知道,在儲存結構體或聯合(struct / union)這樣的複合型變數時,計算機在記憶體空間中開闢一段連續的位置,按照成員變數定義的自然順序進行初始化。但

#pragma pack(n)記憶體方式

在C語言中,結構是一種複合資料型別,其構成元素既可以是基本資料型別(如int、long、float等)的變數,也可以是一些複合資料型別(如陣列、結構、聯合等)的資料單元。在結構中,編譯器為結構的每個成員按其自然對界(alignment)條件分配空間。各個成員按照它們被宣告的順

方式#pragma pack()偽指令及_attribute_aligned_指令

GNU C 的一大特色就是__attribute__ 機制。__attribute__ 可以設定函式屬性(Function Attribute )、變數屬性(Variable Attribute )和型別屬性(Type Attribute )。 __attribute__ 書寫特徵是:__attri

par函數的adj 參數- 控制文字的方式

div 效果 lin .cn 表示 對齊方式 制圖 技術 cnblogs adj 用來控制文字的對齊方式,取值範圍為0到1,控制圖片中x軸和y軸標簽,標題,以及通過text 添加的文字的對齊方式 0表示左對齊,代碼示例: par(adj = 0)plot(1:5, 1:5

方式

align 水平 nbsp text vertical pan font ott -s 水平對齊方式--text-align屬性 left 左 默認值 right 右 center 中 justify 兩端對齊垂直對齊--

CSS3----vertical-align(文本垂直方式

title sel png ont itl ase pla otto contain 一、代碼: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <

IntelliJ IDEA設置代碼括號方式

har size pop class post 括號 成功 tar 圖片 IntelliJ IDEA設置代碼括號對齊方式 IntelliJ IDEA默認的對齊方式如下:括號跟函數名在一行 想改為括號獨自占一行,如下: 配置方式如下:File

34 文本樣式 1 word-spacing單詞間距 letter-spacing 字母間距 2 text-align 文本方式 justify 兩端 3 text-indent 首行縮進

letter com 分享圖片 inf nbsp png 技術分享 方式 bubuko 1 2 3 34 文本樣式 1 word-spacing單詞間距 letter-spacing 字母間距 2 text-align 文本對齊方式 justify 兩端對齊 3

記事本:如何將16進位制數賦給int型變數,再按16進位制輸出,以及電腦大小端方式測試。

c和c++版本:          int i=0x12345678;          printf("%hx",i); java版本:      

python學習之網站的編寫(HTML,CSS,JS)(十三)----------CSS字型和方式的設定

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>逆水行舟不進則退</title> </head> <b

一種巢狀式柵欄佈局的方式

轉載自CSDN本文連結地址: 一種巢狀式柵欄佈局的對齊方式 在bootstrap的應用中,經常需要對柵格進行巢狀佈局,但也因為如此,很容易出現內容無法對齊的現象。 UI給定的要求是兩欄表格佈局,文字與輸入框的佔比為1:3,詳細布局檔案見下圖。 幾乎不用思考,我們就能很快寫出

C++中結構體的方式

在面試中,常會考到結構體的對齊方式,因此對其進行總結。 1、在沒有#pragma pack巨集的情況下     struct sA{ double d1; int i1; double d2; char c1;

CSS 下拉內容的方式

<!DOCTYPE html > <html> <head> <meta charset="utf-8"> <title>自學教程

Android中UI之方式

UI中的對齊方式: 一、LinearLayout(線性佈局) 提供了控制元件水平垂直排列的模型,同時可以通過設定子控制元件的weight佈局引數控制各個控制元件在佈局中的相對大 小。 水平(vertical)垂直(horizontal) fill-parent:佔滿整個螢幕 wr

Java將資料按列寫入Excel並設定格式(字型、背景色、自動列寬、方式等)

本文使用jxl.jar工具類庫將資料按列寫入Excel並設定格式(字型、背景色、自動列寬、對齊方式等)。 /** * 按列寫入Excel並設定格式 * * @param outputUrl * 輸出路徑 * @par

CSS——文字方式

橫向對齊 方法1:單行塊級元素水平居中只用新增text-align即可,如P標籤,垂直居中vertical-align只適用於行內元素與單元格,所以設定行高與塊高度相同即可 text-align: center; 方法2:普通的文字居中只要設定text-ali

Markdown 中控制圖片的大小 方式

普通展示圖片 MarkDown中顯示圖片的語法是 ![圖片描述](圖片地址) 。但是這種方法只是單純把圖片顯示出來,如果圖片很大的話就會鋪滿螢幕或者超高,排版上不好看。 通過img標籤控制寬高 &