最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

c語言結(jié)構(gòu)體字節(jié)對齊的實(shí)現(xiàn)方法

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

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

在c語言的結(jié)構(gòu)體里面一般會按照某種規(guī)則去進(jìn)行字節(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個(gè)字節(jié)

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

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

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

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

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

假設(shè)有這樣一個(gè)結(jié)構(gòu)體如下:

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

假設(shè)地址空間是類似下面這樣的:

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

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

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

3.手動設(shè)置對齊

什么情況下需要手動設(shè)置對齊:

  • 設(shè)計(jì)不同CPU下的通信協(xié)議,比如兩臺服務(wù)器之間進(jìn)行網(wǎng)絡(luò)通信,共用一個(gè)結(jié)構(gòu)體時(shí),需要手動設(shè)置對齊規(guī)則,確保兩邊結(jié)構(gòu)體長度一直;
  • 編寫硬件驅(qū)動程序時(shí)寄存器的結(jié)構(gòu);

手動設(shè)置對齊方式有兩種:

代碼里添加預(yù)編譯標(biāo)識:

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

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

定義結(jié)構(gòu)體時(shí):

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

4.結(jié)構(gòu)體比較方法

可以使用內(nèi)存比較函數(shù)memcpy進(jìn)行結(jié)構(gòu)體比較,但因?yàn)榻Y(jié)構(gòu)體對齊可能會有填充位不一致的情況,此時(shí)需要注意:

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

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

相關(guān)文章

  • C++中std::tuple和std::pair的實(shí)現(xiàn)

    C++中std::tuple和std::pair的實(shí)現(xiàn)

    std::tuple和std::pair是兩種極具實(shí)用性的數(shù)據(jù)結(jié)構(gòu),本文主要介紹了C++中std::tuple和std::pair的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-02-02
  • C++11關(guān)于auto關(guān)鍵字的使用示例

    C++11關(guān)于auto關(guān)鍵字的使用示例

    今天小編就為大家分享一篇關(guān)于C++11關(guān)于auto關(guān)鍵字的使用示例,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • C語言、C++內(nèi)存對齊問題詳解

    C語言、C++內(nèi)存對齊問題詳解

    這篇文章主要介紹了C語言、C++內(nèi)存對齊問題詳解,內(nèi)存對齊的問題主要存在于理解struct和union等復(fù)合結(jié)構(gòu)在內(nèi)存中的分布,需要的朋友可以參考下
    2014-10-10
  • C語言實(shí)現(xiàn)堆的簡單操作的示例代碼

    C語言實(shí)現(xiàn)堆的簡單操作的示例代碼

    堆(heap)是計(jì)算機(jī)科學(xué)中一類特殊的數(shù)據(jù)結(jié)構(gòu)的統(tǒng)稱。堆通常是一個(gè)可以被看做一棵樹的數(shù)組對象。本文介紹了C語言中堆的一些簡單操作,需要的可以參考一下
    2022-11-11
  • 關(guān)于C++中由于字節(jié)對齊引起內(nèi)存問題定位分析

    關(guān)于C++中由于字節(jié)對齊引起內(nèi)存問題定位分析

    前幾天遇到一個(gè)稀奇古怪的問題,在創(chuàng)建對象的時(shí)候程序異常退出,查找代碼發(fā)現(xiàn)結(jié)構(gòu)體數(shù)組問題,最終把問題簡化得到解決方法,下面小編把我的問題及解決方案分享到腳本之家平臺供大家參考下
    2021-06-06
  • C語言非遞歸算法解決快速排序與歸并排序產(chǎn)生的棧溢出

    C語言非遞歸算法解決快速排序與歸并排序產(chǎn)生的棧溢出

    上期我們講完了排序算法下,不知道小伙伴們有沒有發(fā)現(xiàn)一個(gè)問題,快速排序和歸并排序我們都是用遞歸來實(shí)現(xiàn)的,可能有小伙伴會問,如果說數(shù)據(jù)量很多話,棧區(qū)空間會不會不夠用呢?這期我們就來解決使用遞歸實(shí)現(xiàn)的排序?qū)е聴R绯鋈绾谓鉀Q
    2022-04-04
  • C++ 中消息隊(duì)列函數(shù)實(shí)例詳解

    C++ 中消息隊(duì)列函數(shù)實(shí)例詳解

    這篇文章主要介紹了C++ 中消息隊(duì)列函數(shù)實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • 詳解C語言中scanf函數(shù)使用的一些注意點(diǎn)

    詳解C語言中scanf函數(shù)使用的一些注意點(diǎn)

    這篇文章主要介紹了C語言中scanf函數(shù)使用的一些注意點(diǎn),scanf函數(shù)的使用是C語言入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2016-04-04
  • QT線程池的使用(QThreadPool類和QRunnable類)

    QT線程池的使用(QThreadPool類和QRunnable類)

    本文主要介紹了QT線程池的使用(QThreadPool類和QRunnable類),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • C++ 仿函數(shù)使用講解

    C++ 仿函數(shù)使用講解

    這篇文章主要介紹了C++ 仿函數(shù)使用講解,本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-09-09

最新評論

米林县| 东乌珠穆沁旗| 抚远县| 镇巴县| 宁陵县| 仁布县| 余江县| 祁东县| 中宁县| 乌兰浩特市| 井冈山市| 伊吾县| 墨竹工卡县| 清徐县| 宜州市| 白河县| 保德县| 平顺县| 绥德县| 鹿泉市| 扎鲁特旗| 淮滨县| 绥棱县| 嘉义县| 临江市| 娱乐| 黔西| 五华县| 正安县| 平湖市| 乌什县| 平度市| 梁河县| 闵行区| 于都县| 岗巴县| 泉州市| 天台县| 武隆县| 加查县| 丹东市|