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

結(jié)構(gòu)體對(duì)齊的規(guī)則詳解及C++代碼驗(yàn)證

 更新時(shí)間:2021年08月16日 16:42:12   投稿:BJT  
在c語言的結(jié)構(gòu)體里面一般會(huì)按照某種規(guī)則去進(jìn)行字節(jié)對(duì)齊。本文就來介紹一下如何實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解下

基本概念

CPU一次能讀取多少個(gè)字節(jié)的數(shù)據(jù)主要是看數(shù)據(jù)總線是多少位的,16位CPU一次能讀取2個(gè)字節(jié),32位CPU一次能讀取4個(gè)字節(jié),64位CPU一次能讀取8個(gè)字節(jié)。并且不能跨內(nèi)存區(qū)間訪問,這句話的意思可以理解為,如果CPU是32位的話,那么可以將整個(gè)內(nèi)存區(qū)間每4個(gè)字節(jié)分為一塊(BLOCK),每次讀取一個(gè)BLOCK的數(shù)據(jù)。

那么對(duì)于下面這個(gè)結(jié)構(gòu)體:

struct st {
    char c;
    int i;
};

如果不進(jìn)行對(duì)齊操作,char 的地址范圍0x00000000,int的地址范圍為0x00000001----0x00000004,int分布在兩個(gè)不同的BLOCK上,因此要讀取int需要兩次操作;如果進(jìn)行4字節(jié)對(duì)齊,那么int的地址范圍為0x00000004----0x00000007,處在一個(gè)BLOCK上,因此只需一次讀取操作即可。缺點(diǎn)也顯而易見,多占用了3個(gè)字節(jié)。這也是典型的一種空間換時(shí)間的方法吧。

結(jié)構(gòu)體對(duì)齊的規(guī)則

結(jié)構(gòu)體對(duì)齊需要滿足以下三條規(guī)則,其中系統(tǒng)對(duì)齊模數(shù)在64位機(jī)器上默認(rèn)為8字節(jié),32位機(jī)器上默認(rèn)為4字節(jié)。通過預(yù)處理指令#pargma pack(N)可以修改系統(tǒng)模數(shù)為N個(gè)字節(jié)。

1、以結(jié)構(gòu)體第一個(gè)元素的地址為起始地址,亦即結(jié)構(gòu)體的起始地址。由上可知,第一個(gè)元素的偏移量為0;

2、結(jié)構(gòu)體元素對(duì)齊原則:結(jié)構(gòu)體成員的對(duì)齊模數(shù)為類型大小與系統(tǒng)對(duì)齊模數(shù)的較小者;結(jié)構(gòu)體成員的偏移量(填充)為對(duì)齊模數(shù)的整數(shù)倍。

3、結(jié)構(gòu)體大小對(duì)齊原則:結(jié)構(gòu)體的對(duì)齊模數(shù)為結(jié)構(gòu)體最大元素與系統(tǒng)對(duì)齊模數(shù)的較小者;結(jié)構(gòu)體的大?。ㄌ畛洌榻Y(jié)構(gòu)體對(duì)齊模數(shù)的整數(shù)倍。

程序驗(yàn)證

測(cè)試環(huán)境為64位Windows ,VS2019,定義結(jié)構(gòu)體st1,包含3個(gè)元素char,int,double,定義系統(tǒng)對(duì)齊模數(shù)為4個(gè)字節(jié)。

#include <iostream>

#pragma pack(4)

using Tsize = unsigned long long;
using namespace std;

struct st1 {
    char c;
    int i;
    double db;
    Tsize ch_offset() {
        return Tsize((Tsize)&this->c - (Tsize)this);
    }
    Tsize int_offset() {
        return Tsize((Tsize)&this->i - (Tsize)this);
    }
    Tsize double_offset() {
        return Tsize((Tsize)&this->db - (Tsize)this);
    }
};

int main() {
    cout << "st1結(jié)構(gòu)體大小" << sizeof(st1) << endl;
    cout << "char 偏移量=" << st1().ch_offset() << endl;
    cout << "int偏移量=" << st1().int_offset() << endl;
    cout << "double偏移量=" << st1().double_offset() << endl;
    return 0;
}

首先我們按照對(duì)齊規(guī)則來進(jìn)行分析。第一個(gè)元素為char,類型大小為1個(gè)字節(jié),對(duì)齊模數(shù)min(1,4)=1,偏移量為0是對(duì)齊模數(shù)的整數(shù)倍,無需填充(從這里我們可以看到,第一個(gè)字節(jié)偏移量始終為0,是不需要填充的),下一個(gè)元素的偏移從1開始;第二個(gè)元素為int,類型大小4個(gè)字節(jié),對(duì)齊模數(shù)為4個(gè)字節(jié),不填充時(shí)偏移量為1,不是4的整數(shù)倍,因此這里需要填充3個(gè)字節(jié),使得int的偏移量為4,且下一個(gè)元素偏移從8開始;第三個(gè)元素是double,類型大小為8個(gè)字節(jié),對(duì)齊模數(shù)為4,偏移量從8開始,是4的整數(shù)倍,因此無需填充,占用8個(gè)字節(jié),因此結(jié)構(gòu)體的大小為16個(gè)字節(jié)。運(yùn)行程序輸出:

在這里插入圖片描述

將系統(tǒng)對(duì)齊模數(shù)修改為1 【#pargma pack(1)】,這樣的話,任何情況下都無需填充(不足一個(gè)字節(jié)的類型視為一個(gè)字節(jié)),結(jié)構(gòu)體的大小即為結(jié)構(gòu)體元素大小之和。運(yùn)行程序輸出:

在這里插入圖片描述

將系統(tǒng)對(duì)齊模數(shù)修改為8 【#pargma pack(8)】,這樣的話,任何情況下都無需填充(不足一個(gè)字節(jié)的類型視為一個(gè)字節(jié)),結(jié)構(gòu)體的大小即為結(jié)構(gòu)體元素大小之和。運(yùn)行程序輸出:

在這里插入圖片描述

Emmm,好像和系統(tǒng)對(duì)齊模數(shù)為4時(shí)沒什么變化。那我們將int 和 double的順序換一下呢?

#include <iostream>

#pragma pack(8)

using Tsize = unsigned long long;
using namespace std;

struct st1 {
    char c;
    double db;
    int i;
    Tsize ch_offset() {
        return Tsize((Tsize)&this->c - (Tsize)this);
    }
    Tsize int_offset() {
        return Tsize((Tsize)&this->i - (Tsize)this);
    }
    Tsize double_offset() {
        return Tsize((Tsize)&this->db - (Tsize)this);
    }
};

int main() {
    cout << "st1結(jié)構(gòu)體大小" << sizeof(st1) << endl;
    cout << "char 偏移量=" << st1().ch_offset() << endl;
    cout << "double偏移量=" << st1().double_offset() << endl;
    cout << "int偏移量=" << st1().int_offset() << endl;
    return 0;
}

在這里插入圖片描述

順序調(diào)了下,結(jié)構(gòu)體就比原來大了8個(gè)字節(jié)!!!從中我們可以看出,將結(jié)構(gòu)體元素從小到大排列,可以最大程度節(jié)省空間。

總結(jié)

本篇文章就到這里了,希望能給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • C++ 獲取dll當(dāng)前路徑下所有文件

    C++ 獲取dll當(dāng)前路徑下所有文件

    本文主要介紹了C++ 獲取dll當(dāng)前路徑下所有文件,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-09-09
  • C++實(shí)現(xiàn)哈希桶的詳細(xì)教程

    C++實(shí)現(xiàn)哈希桶的詳細(xì)教程

    這篇文章主要介紹了C++實(shí)現(xiàn)哈希桶的詳細(xì)教程,哈希的底層是一個(gè)vector的數(shù)組,數(shù)組中的每個(gè)節(jié)點(diǎn)都有一個(gè)pair類型的數(shù)據(jù),文中通過代碼示例和圖文講解的非常詳細(xì),具有一定的參考價(jià)值,需要的朋友可以參考下
    2024-06-06
  • C++實(shí)現(xiàn)隨機(jī)生成迷宮地牢

    C++實(shí)現(xiàn)隨機(jī)生成迷宮地牢

    這篇文章主要介紹了C++實(shí)現(xiàn)隨機(jī)生成迷宮地牢的相關(guān)資料及代碼分享,推薦給大家,有需要的小伙伴可以參考下。
    2015-03-03
  • C++ 虛函數(shù)與純虛函數(shù)的使用與區(qū)別

    C++ 虛函數(shù)與純虛函數(shù)的使用與區(qū)別

    本文主要介紹了C++ 虛函數(shù)與純虛函數(shù)的使用與區(qū)別,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • 淺談C++ 虛函數(shù)分析

    淺談C++ 虛函數(shù)分析

    這篇文章主要介紹了淺談C++ 虛函數(shù)分析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • QString的常用方法(小結(jié))

    QString的常用方法(小結(jié))

    這篇文章主要介紹了QString的常用方法(小結(jié)),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • C++ opencv實(shí)現(xiàn)的把藍(lán)底照片轉(zhuǎn)化為白底照片功能完整示例

    C++ opencv實(shí)現(xiàn)的把藍(lán)底照片轉(zhuǎn)化為白底照片功能完整示例

    這篇文章主要介紹了C++ opencv實(shí)現(xiàn)的把藍(lán)底照片轉(zhuǎn)化為白底照片功能,結(jié)合完整實(shí)例形式詳細(xì)分析了C++使用opencv模塊進(jìn)行圖片轉(zhuǎn)換操作的相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2019-12-12
  • c++ 遞歸鎖的使用示例代碼

    c++ 遞歸鎖的使用示例代碼

    這篇文章主要介紹了c++ 遞歸鎖的使用示例代碼,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-08-08
  • C++關(guān)于size_t的bug解決案例

    C++關(guān)于size_t的bug解決案例

    這篇文章主要為大家介紹了C++關(guān)于size_t的bug解決案例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • C語言版學(xué)生成績(jī)管理系統(tǒng)

    C語言版學(xué)生成績(jī)管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語言版學(xué)生成績(jī)管理系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01

最新評(píng)論

环江| 兴化市| 通海县| 许昌市| 新余市| 通州区| 宽城| 芦溪县| 玉龙| 湛江市| 永新县| 本溪市| 仪征市| 屏山县| 隆德县| 林口县| 海丰县| 鹤峰县| 临澧县| 莲花县| 辽中县| 砀山县| 屯昌县| 安乡县| 张家口市| 海林市| 宕昌县| 梁河县| 南丰县| 泌阳县| 安吉县| 吐鲁番市| 房山区| 光泽县| 刚察县| 彝良县| 平阴县| 遵义县| 扬中市| 松滋市| 宝丰县|