欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

c語言結構體字節(jié)對齊的實現方法

 更新時間:2021年07月27日 10:40:09   作者:cpp加油站  
在c語言的結構體里面一般會按照某種規(guī)則去進行字節(jié)對齊。本文就來介紹一下如何實現,具有一定的參考價值,感興趣的可以了解下

1.什么是字節(jié)對齊

在c語言的結構體里面一般會按照某種規(guī)則去進行字節(jié)對齊。

我們先看一段代碼:

struct st1
{
 char name;
 double age;
 char sex;
};
//32位下 sizeof(struct st1) = 16
//64位下 sizeof(struct st1) = 24
struct st2
{
 char a;
 char b;
 char c;
};
//32位和64位下, sizeof(struct st2)都是3個字節(jié)

從以上結果可以看出,結構體st1在32位下是按照4個字節(jié)來對齊的,在64位下則是按照8個字節(jié)來對齊的,結構體st2則不管32位還是64位則都是按照1個字節(jié)對齊的。
那么我們可以總結出對齊規(guī)則如下:

  • 在所有結構體成員的字節(jié)長度都沒有超出操作系統(tǒng)基本字節(jié)單位(32位操作系統(tǒng)是4,64位操作系統(tǒng)是8)的情況下,按照結構體中字節(jié)最大的變量長度來對齊;
  • 若結構體中某個變量字節(jié)超出操作系統(tǒng)基本字節(jié)單位,那么就按照系統(tǒng)字節(jié)單位來對齊。

注意:并不是32位就直接按照4個字節(jié)對齊,64位按照8個字節(jié)對齊。

2.為什么要有字節(jié)對齊

首先普及一點小知識,cpu一次能讀取多少內存要看數據總線是多少位,如果是16位,則一次只能讀取2個字節(jié),如果是32位,則可以讀取4個字節(jié),并且cpu不能跨內存區(qū)間訪問。

假設有這樣一個結構體如下:

struct st3
{
    char a;
    int b;
};
//那么根據我們第1節(jié)所說的規(guī)則,在32位系統(tǒng)下,它就應該是8個字節(jié)的。

假設地址空間是類似下面這樣的:

在沒有字節(jié)對齊的情況下,變量a就是占用了0x00000001這一個字節(jié),而變量b則是占用了0x00000002~0x000000005這四個字節(jié),那么cpu如果想從內存中讀取變量b,首先要從變量b的開始地址0x00000002讀到0x0000004,然后再讀取一次0x00000005這個字節(jié),相當于讀一個int,cpu從內存讀取了兩次。

而如果進行字節(jié)對齊的話,變量a還是占用了0x00000001這一個字節(jié),而變量b則是占用了0x00000005~0x00000008這四個字節(jié),那么cpu要讀取變量b的話,就直接一次性從0x00000005讀到0x00000008,就一次全部讀取出來了。

所以說,字節(jié)對齊的根本原因其實在于cpu讀取內存的效率問題,對齊以后,cpu讀取內存的效率會更快。但是這里有個問題,就是對齊的時候0x00000002~0x00000004這三個字節(jié)是浪費的,所以字節(jié)對齊實際上也有那么點以空間換時間的意思,具體寫代碼的時候怎么選擇,其實是看個人的。

3.手動設置對齊

什么情況下需要手動設置對齊:

  • 設計不同CPU下的通信協(xié)議,比如兩臺服務器之間進行網絡通信,共用一個結構體時,需要手動設置對齊規(guī)則,確保兩邊結構體長度一直;
  • 編寫硬件驅動程序時寄存器的結構;

手動設置對齊方式有兩種:

代碼里添加預編譯標識:

//用法如下
#pragma pack(n)//表示它后面的代碼都按照n個字節(jié)對齊
struct st3
{
    char a;
    int b;
};
#pragma pack()//取消按照n個字節(jié)對齊,是對#pragma pack(n)的一個反向操作
//這里計算sizeof(st3)=5

上面這兩行其實就類似于開車的時候,走到某一段路的時候,發(fā)現一個限速60公里的指示牌,過了那一段路以后,又會有解除限速60公里的指示牌。

定義結構體時:

//用法如下
struct bbb
{
   char a;
   int b;
}__attribute__((packed));//直接按照實際占用字節(jié)來對齊,其實就是相當于按照1個字節(jié)對齊了
//這里計算sizeof(st3)=5

4.結構體比較方法

可以使用內存比較函數memcpy進行結構體比較,但因為結構體對齊可能會有填充位不一致的情況,此時需要注意:

  • 設置為1個字節(jié)對齊,使它沒有空位;
  • 事先對結構體進行初始化;
memcpy(char *dest, const char* src, int len); //頭文件#include<string.h>

到此這篇關于c語言結構體字節(jié)對齊的實現方法的文章就介紹到這了,更多相關c語言結構體字節(jié)對齊內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Qt編譯OpenCV的實現步驟

    Qt編譯OpenCV的實現步驟

    本文主要介紹了Qt編譯OpenCV的實現步驟,通過詳細的步驟和說明,幫助開發(fā)者在Qt環(huán)境中成功集成并編譯OpenCV,從而為各類計算機視覺項目提供強大的支持,感興趣的可以了解一下
    2024-01-01
  • C++中的explicit關鍵字詳解

    C++中的explicit關鍵字詳解

    這篇文章主要介紹了C++中的explicit關鍵字詳解,文章圍繞主題展開詳細的內容介紹,具有一定的參考價值,需要的朋友可以參考一下
    2022-07-07
  • C++求解二叉樹的下一個結點問題

    C++求解二叉樹的下一個結點問題

    本文將通過C++求解以下問題:給定一個二叉樹其中的一個結點,請找出中序遍歷順序的下一個結點并且返回。文中示例代碼講解詳細,感興趣的可以了解一下
    2022-04-04
  • C語言進階二叉樹的基礎與銷毀及層序遍歷詳解

    C語言進階二叉樹的基礎與銷毀及層序遍歷詳解

    朋友們好,這篇播客我們繼續(xù)C++的初階學習,現在對我們對C++的二叉樹基礎oj與二叉樹銷毀和層序遍歷進行練習,讓我們相互學習,共同進步
    2022-06-06
  • windows系統(tǒng)下C++調用matlab程序的方法詳解

    windows系統(tǒng)下C++調用matlab程序的方法詳解

    這篇文章主要給大家介紹了關于在windows系統(tǒng)下C++調用matlab程序的方法,文中通過示例代碼介紹的非常詳細,對大家學習或者使用C++具有一定的參考學習價值,需要的朋友們下面跟著小編來一起學習學習吧。
    2017-08-08
  • C語言中typedef的用法以及#define區(qū)別詳解

    C語言中typedef的用法以及#define區(qū)別詳解

    這篇文章主要給大家介紹了關于C語言中typedef用法以及#define區(qū)別的相關資料,typedef 是用來定義一種類型的新別名的,它不同于宏(#define),不是簡單的字符串替換。而#define只是簡單的字符串替換(原地擴展),需要的朋友可以參考下
    2021-07-07
  • C++面向對象語言自制多級菜單功能實現代碼

    C++面向對象語言自制多級菜單功能實現代碼

    菜單類主要負責菜單的創(chuàng)建、修改、刪除,是包含菜單結構組織和響應函數的模型,用戶擁有充分的自主性,可根據需要自定義菜單顯示和響應函數,這篇文章主要介紹了C++面向對象語言自制多級菜單,需要的朋友可以參考下
    2024-06-06
  • 手把手教你如何一眼分辨是C還是C++

    手把手教你如何一眼分辨是C還是C++

    在很大程度上,C++是C的超集,這意味著一個有效的C程序也是一個有效的C++程序,下面這篇文章主要給大家介紹了關于如何一眼分辨是C還是C++的相關資料,需要的朋友可以參考下
    2023-02-02
  • C++中cin的返回值問題

    C++中cin的返回值問題

    這篇文章主要介紹了C++中cin的返回值問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • C++實現學生信息管理系統(tǒng)(完整版)

    C++實現學生信息管理系統(tǒng)(完整版)

    這篇文章主要為大家詳細介紹了C++實現學生信息管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06

最新評論