程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 淺談C言語的字節對齊 #pragma pack(n)2

淺談C言語的字節對齊 #pragma pack(n)2

編輯:關於C++

淺談C言語的字節對齊 #pragma pack(n)2。本站提示廣大學習愛好者:(淺談C言語的字節對齊 #pragma pack(n)2)文章只能為提供參考,不一定能成為您想要的結果。以下是淺談C言語的字節對齊 #pragma pack(n)2正文


#pragma pack(n)

這是給編譯器用的參數設置,有關構造體字節對齊方式設置, #pragma pack是指定數據在內存中的對齊方式。

#pragma pack (n)   作用:C編譯器將依照n個字節對齊。
#pragma pack ()     作用:取消自定義字節對齊方式。


#pragma  pack (push,1)     作用:是指把原來對齊方式設置壓棧,並設新的對齊方式設置為一個字節對齊

#pragma pack(pop)  作用:恢復對齊形態

因而可見,參加push和pop可以使對齊恢復到原來形態,而不是編譯器默許,可以說後者更優,但是很多時分兩者差異不大

如:

#pragma pack(push) //保管對齊形態

#pragma pack(4)//設定為4字節對齊

相當於 #pragma  pack (push,4) 

解釋一:

每個特定平台上的編譯器都有自己的默許“對齊系數”(也叫對齊模數)。順序員可以經過預編譯命令#pragma pack(n),n=1,2,4,8,16來改動這一系數,其中的n就是你要指定的“對齊系數”。

規則:

1、數據成員對齊規則:構造(struct)(或結合(union))的數據成員,第一個數據成員放在offset為0的中央,當前每個數據成員的對齊依照#pragma pack指定的數值和這個數據成員本身長度中,比擬小的那個停止。

2、構造(或結合)的全體對齊規則:在數據成員完成各自對齊之後,構造(或結合)自身也要停止對齊,對齊將依照#pragma pack指定的數值和構造(或結合)最大數據成員長度中,比擬小的那個停止。
 

解釋二:

n 字節的對齊方式 VC 對構造的存儲的特殊處置的確進步 CPU 存儲變量的速度,但是有時分也帶來 了一些費事,我們也屏蔽掉變量默許的對齊方式,自己可以設定變量的對齊方式。 VC 中提供了#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(4)

struct node{

 int e;
 char f;
 short int a;
 char b;

};

struct node n;

printf("%d\n",sizeof(n));

我自己算的後果是16,後果實踐後果是:

12

然後構造體外部數據成員變化一下地位:

#pragma pack(4)

struct node{

 char f;
 int e;
 short int a;
 char b;};

struct node n;

printf("%d\n",sizeof(n));

12

將對齊位數強迫定位2

#pragma pack(2)

struct node{

 char f;
 int e;
 short int a;
 char b;};

struct node n;

printf("%d\n",sizeof(n));

10

將對齊位數強迫定位1

#pragma pack(1)

struct node{

 char f;
 int e;
 short int a;
 char b;};

struct node n;

printf("%d\n",sizeof(n));

8

看著輸入後果和文字描繪有點暈,上面復雜說一下俺的斷定規則吧:

其實之所以有內存字節對齊機制,就是為了最大限制的增加內存讀取次數。我們知道CPU讀取速度比內存讀取速度快至多一個數量級,所以為了節省運算破費時間,只能以犧牲空間來換取時間了。

上面舉例闡明如何最大限制的增加讀取次數。

#pragma pack(1)

struct node{

 char f;
 int e;
 short int a;
 char b;};

struct node n;

printf("%d\n",sizeof(n));

這裡強迫依照1字節停止對齊,可以了解成一切的內容都是依照1字節停止讀取(暫且這樣了解,由於這樣可以很好的了解內存對其機制),其他一切的數據成員都是1字節的整數倍,所以也就不必停止內存對其,各個成員在內存中就依照實踐順序停止陳列,構造體實踐長度為8

#pragma pack(2)

struct node{

 char f;
 int e;
 short int a;
 char b;};

struct node n;

printf("%d\n",sizeof(n));

這裡強迫依照2字節停止對齊。假如內存散布依然是延續的話,那麼int e就得三次才干讀到CPU中,所以為了“考究”int e的讀取,所以在char f之後預留1BYTE,最後的char b也是如此,所以長度為10

#pragma pack(4)

struct node{

 char f;
 int e;
 short int a;
 char b;};

struct node n;

printf("%d\n",sizeof(n));

這裡強迫依照4字節停止對齊。所以char f後要預留3BYTE,而short int a 和 char b可以一次讀取到CPU(依照4字節讀取),所以長度為12

假如#pramga pack(n)中的n大於構造體成員中任何一個成員所占用的字節數,則該n值有效。編譯器會選取構造體中最大數據成員的字節數為基准停止對其

以上這篇淺談C言語的字節對齊 #pragma pack(n)2就是分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved