1. 程式人生 > >C語言中的位元組對齊和對程式的影響以及位段的定義

C語言中的位元組對齊和對程式的影響以及位段的定義

C語言中的位元組對齊和對程式的影響

  1. 位元組對齊的概念
  2. 位元組對齊對程式的影響
  3. #pragma指令設定 位元組對齊
  4. 編譯器對位元組對齊的原則
  5. 位元組對齊的程式設計設定
  6. 位段定義

位元組對齊的概念:

現代計算機中記憶體空間都是按照byte來劃分的,從理論上來講,似乎對任何型別的變數的訪問可以從任何地址開始,但是實際情況是在訪問特定型別變數的時候經常在特定的記憶體地址訪問(犧牲記憶體空間來換取讀取的效率);
定義:
    各種型別的資料按照一定的規則在空間上排列,而不是順序的一個接一個的排放,這就是位元組對齊(硬體平臺其實已經處理好了);
原因和作用:
    各種硬體平臺對儲存空間的處理上有很大不同;   
    利用位元組對齊可以提高存取效率;

位元組對齊對程式的影響

位元組對齊對程式的影響:
位元組對齊事例:(假設在32為系統中)

            struct A{
                int a ; //--->實際4個位元組
                char b; //--->實際1個位元組-->位元組對其後2個位元組
                short c;//--->實際2個位元組
            };
sizeof(struct A);//出現的是8個位元組,就是根據位元組對齊來分配的

            struct B{
                char b;  //-->實際1個位元組-->位元組對其後4個位元組
                int a;   //-->實際4個位元組
                short c; //-->實際2個位元組-->位元組對其後4個位元組
            };
sizeof(B); //為12個位元組,
向後面最大的位元組靠攏,保證一個讀取週期能夠完整讀完一個或這多個完整的值

#pragma指令設定位元組對齊

/*按兩個位元組對齊*/
#pragma pack(2) //申請位元組對其方式
struct c{
    char b;
    int a;
    short c;
};
#pragma pack()  //取消對齊方式
sizeof(struct c);//8個位元組
//--------------
/*按照1個位元組來對齊*/
#pragma pack(1)
struct D{
    char b;
    int a;
    short c;
};
#pragma pack();
sizeof(struct D);//輸出為7

編譯器對位元組對齊原則

資料型別自身的對齊
    char型別資料,其自身對齊值為1
    short型別為2
    int float double型別為其自身對齊數值為4
結構體自身對齊數值:齊成員中自身對其值最大的那個數值
通過#pragma來指定對其數值#pragma pack(value);指定位元組對齊
資料成員,結構體的有效對齊值,:自身對齊值和指定對其數值中小的那個   

重要概念:
有效對齊值N :存放起始地址%N = 0;
對齊值圓整:結構體成員變數佔用總長度需要對 結構體有效對齊值的整數倍;

位元組對齊的程式設計設定

空間換取時間:
結構體中的成員按照型別的大小從小到大進行定義,或者從大到小這樣去定義,避免大小不一混亂排列

位段定義

位段的概念:

在計算機中去儲存的時候一般以位元組為單位,實際上,有時儲存一個資訊不必要用一個或者多個位元組,例如”真”和”假”用0或者1來表示,只需1位
在計算機用於過程控制,引數檢測,或者資料通訊領域時,控制資訊往往只戰一個位元組中的一個或者幾個二進位制位,常常一個位元組中放幾個資訊;
C語言中允許在一個結構體中以位為單位來制定成員所佔記憶體的長度,這種以位為單位的成員稱為”位斷”或者稱為”位域(bit field)”,利用未斷能夠用較少的位數>儲存資料,節約空間又方便操作,在特定行業中去使用
位段的定義語法:
型別說明符 [位段名]:位長
位段名可選,位長表示該位段所佔的二進位制位數,不能超過該型別說明符的上限
位段成員的型別說明符號必須以int ,signed , unsigned int
無名的位段是不可以訪問的,但會佔空間愛你
不可以對位段進行去地址操作

事例:
    struct node
    {
        unsigned int a:4; // 位段佔4位 
        unsigned int :0; //無名位段佔0位 
        unsigned int b:4; //位段b佔4位 
        int c:32;   //位段c佔32位
        int :6;     //無名位段佔6位 
    }

相關推薦

C語言位元組程式影響以及定義

C語言中的位元組對齊和對程式的影響 位元組對齊的概念 位元組對齊對程式的影響 #pragma指令設定 位元組對齊 編譯器對位元組對齊的原則 位元組對齊的程式設計設定 位段定義 位元組對齊的概念:

關於C語言資料結構的記憶體問題

 當在C中定義了一個結構型別時,它的大小是否等於各欄位(field)大小之和?編譯器將如何在記憶體中放置這些欄位?ANSI   C對結構體的記憶體佈局有什麼要求?而我們的程式又能否依賴這種佈局?這些問題或許對不少朋友來說還有點模糊,那麼本文就試著探究它們背後的祕密。    

C語言無符號數有符號數相加比較的問題

轉自https://blog.csdn.net/supreme42/article/details/6687781 看個題: #include<stdio.h> int main() { unsigned int a=6; int b=-20; printf("%d\n"

C語言的淺拷貝深拷貝

淺拷貝 首先看下面這段程式碼: # include<assert.h> # include<string.h> #include <stdlib.h> typedef struct Node//定義了一個結構體 { int size; char *da

C語言的隨機數 srand ( ) rand ( )

在C語言中,生成一個隨機數,一般利用兩個函式,即void srand ( unsigned int seed ) 和 int rand ( void )。     srand() 函式用於生成一個隨機數種子,種子的值等於引數seed,這個引數由我們指定一個

C語言的單引號雙引號的區別

  首先肯定地說,二者是有區別的,不是說用誰都一樣。 1、實質區別,代表的含義不同 'A'代表的是一個整數,而且這個整數對應的是編譯器所採用的字符集中的字元序列對應的數值。所以'A'跟ASCII中的65意義是相同的。 1 # include <iostream>

C語言的指標陣列陣列指標

可以將 *string看成陣列 a[] 下的a,即指標是指向陣列的首地址的; 指標陣列是陣列元素為指標的陣列(例如 int *p[3],定義了p[0],p[1],p[2]三個指標),其本質為陣列。 指

C 語言的結構體共用體(聯合體)

本文主要總結了譚浩強主編的《C 程式設計》教材中結構體和共用體相關章節的內容。 在 C 語言中, 結構體(struct) 是一個或多個變數的集合,這些變數可能為不同的型別,為了處理的方便而將這些變數組織在一個名字之下。由於結構體將一組相關變數看作一個單元而不是各自獨立的實體,因此結構體有助於組織複雜的資料,

C語言變數的宣告定義

變數宣告和變數定義變數定義:用於為變數分配儲存空間,還可為變數指定初始值。程式中,變數有且僅有一個定義。變數宣告:用於向程式表明變數的型別和名字。定義也是宣告,extern宣告不是定義定義也是宣告:當定義變數時我們聲明瞭它的型別和名字。extern宣告不是定義:通過使用ext

C語言棧的建立應用

棧的特點為: 先進後出(first in last out)。 棧中有兩個指標,棧頂指標和棧尾指標。其中,棧尾指標是不動的。用棧頂指標等於棧尾指標來判定棧是否為空。壓棧時,將棧頂指標+1,然後將資料存

C語言的靜態變數普通變數的區別

下面用程式碼說明: 一個可執行程式包括BSS段、資料段、程式碼段(文字段)。 bss segment ,data segment ,code/text segment ①BSS(Block by Start Symbol) :通常指用來存放程式中未初化的全域性變數和靜態變數

關於C語言返回區域性變數區域性指標變數

char *test1(void) { char b[10] = "abcde"; return b; } char *test1_ver2(void) { static char b[10] = "abcde"; return b; } char *test2(voi

C語言指標初始化常規運算

1. 指標初始化注意須知 <1>指標變數和普通變數一樣,外部或者靜態指標變數若未初始化,則被自動初始化為NULL,它的值為0(ASCII字元NULL的程式碼)。 <2>可以

C語言樹的建立遍歷

樹的遍歷分為三種:前序遍歷(根左右),中序遍歷(左根右),後序遍歷(左右根)。 PS:根左右,就是先遍歷根節點,然後是左子樹,最後是右子樹。如下圖: 前序遍歷:ABDECF。 中序遍歷:DBEACF

C語言的字元變數字元常量

字元變數與字元常量定義   1.字元變數:char型別定義的變數   2.字元常量:一個字元常量代表ASCII字符集中的一個字元,在程式中用單引號把一個字元括起來作為字元常量 字元常量的表示形式   1.用字元的圖形符號表示,如:‘a’,‘y’   2.直接用十進位制的資料

C語言的子函式主函式有什麼聯絡啊?它們是怎麼編寫的?

函式定義的一般形式1.無參函式的一般形式 型別說明符 函式名() { 型別說明 語句 }  其中型別說明符和函式名稱為函式頭。 型別說明符指明瞭本函式的型別,函式的型別實際上是函式返回值的型別。 該型別說明符與第二章介紹的各種說明符相同。 函式名是由使用者定義的識別符號,函式名後有一個空括號,其中無引數,但括

C語言各資料型別他們對應的最大值最小值的常量

C中各種型別的最大值最小值常量定義在”limits.h”和”float.h”中。 CHAR_MIN和CHAR_MAX分別表示有符號小整型的最小值和最大值,UCHAR_MAX表示無符號小整型的最大值; SHRT_MIN和SHRT_MAX分別表示有符號短整型的最

C語言的語法錯誤語義錯誤

語法錯誤 1:如果不遵循C語言的規則就會犯語法錯誤,它類似於英語中的語法錯誤。 例如(Bugs frustrate be can)這句英語    可以看出句子中的英語單詞都是正確的,但是沒有按照正確的順序組織句子。c的語法錯誤就是指正確的c符號放在了錯誤的位置。  那麼如何

C語言位元組問題(以32系統為例)

  1. 什麼是對齊?   現代計算機中記憶體空間都是按照位元組(byte)劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何地址開始,但實際情況是在訪問特定變數的時候經常在特定的記憶體地址訪問,這就需要各型別資料按照一定的規則在空間上排列,而不是順序地一個接一個地排放,這就是對齊

c語言指標陣列陣列指標的認識

1.陣列:一批具有同名的同屬性的資料就組成了一個數組。(“[ ]”也是陣列型別的一部分)     由此可知:(1)陣列是一組有序資料的集合;(2)陣列中的每一個元素都屬於同一個資料型別。  定義一維陣列的一般形式:型別符  陣列名【常量表達式】(陣列也