91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何設(shè)計只有數(shù)據(jù)字段的結(jié)構(gòu)體

開關(guān)電源芯片 ? 來源:程序喵大人 ? 作者:程序喵大人 ? 2021-08-23 09:37 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

之前寫過一篇《如何設(shè)計一個C++的類》,今天這里繼續(xù)聊聊如何設(shè)計結(jié)構(gòu)體,注意本文不介紹在C++中結(jié)構(gòu)體和類具體有什么區(qū)別,本文所說的結(jié)構(gòu)體是指只有數(shù)據(jù)字段不帶任何函數(shù)的那種結(jié)構(gòu)體。

當(dāng)創(chuàng)建結(jié)構(gòu)體的實例時,結(jié)構(gòu)體的數(shù)據(jù)成員會按其聲明的順序連續(xù)存儲。然而,這個聲明的順序也是有學(xué)問的,順序不同結(jié)構(gòu)體的大小可能有很大差別,數(shù)據(jù)成員的訪問性能也可能會有很大區(qū)別!

這里涉及一個概念:內(nèi)存對齊。關(guān)于內(nèi)存對齊我之前寫過一篇文章:《內(nèi)存對齊》,這里不深入討論,只是簡單介紹一下。

大多數(shù)編譯器會對齊數(shù)據(jù)成員,會以四舍五入地址方式來優(yōu)化數(shù)據(jù)的訪問,如下表所示。

0c708e52-02f8-11ec-9bcf-12bb97331649.jpg

這種內(nèi)存對齊可能會在成員大小混合的結(jié)構(gòu)體中產(chǎn)生未使用字節(jié)的空洞。

例如:

struct S {

short int a; // 2字節(jié)

// 6個空洞

double b; // 8

int d; // 4

// 4個空洞

};

S ArrayOfStructures[100];

這里,在a和b之間有6個未使用的字節(jié),因為b必須從一個能被8整除的地址開始。

最后還有4個未使用的字節(jié)空洞。這樣做的原因是,數(shù)組中S的下一個實例必須從一個能被8整除的地址開始,以便將其b成員以8對齊。

然而,如果改變一下結(jié)構(gòu)體中數(shù)據(jù)成員聲明的順序,通過將最小的成員放在最后,未使用的字節(jié)數(shù)可以減少到2:

struct S {

double b; // 8

int d; // 4

short int a; // 2

// 2個空洞

};

S ArrayOfStructures[100];

這種重新排序使結(jié)構(gòu)體變小了8個字節(jié),那整個數(shù)組則變小了800個字節(jié)。

在此特性上,類和結(jié)構(gòu)體相同。通過重新排序數(shù)據(jù)成員,結(jié)構(gòu)體對象和類對象通??梢宰兊酶?。如果類至少有一個虛成員函數(shù),則在第一個數(shù)據(jù)成員之前或最后一個成員之后會有一個指向虛函數(shù)表的指針。該指針在32位系統(tǒng)中為4字節(jié),在64位系統(tǒng)中為8字節(jié)。

如果不確定結(jié)構(gòu)體或它的每個成員有多大,可以使用sizeof操作符進(jìn)行一些測試。sizeof操作符返回的值包括對象末尾的任何未使用的字節(jié)(內(nèi)存對齊后的字節(jié)數(shù))。

還有一個知識點:

如果數(shù)據(jù)成員相對于結(jié)構(gòu)體或類開頭的偏移量小于128,則訪問數(shù)據(jù)成員的代碼會更加緊湊,因為該偏移量可以使用8位有符號的數(shù)字來表示。如果相對于結(jié)構(gòu)體或類的開頭的偏移量是128字節(jié)或更多,那么偏移量必須表示為一個32位數(shù)字(指令集在8位到32位之間沒有偏移量)。例如:

struct S {

int a[100]; // 400

int b; // 4

int read() { return b; }

};

b成員的偏移量是400。任何通過指針或成員函數(shù)訪問b字段的代碼都需要將偏移量編碼為32位數(shù)字。如果交換a和b,則兩者都可以通過編碼為8位有符號數(shù)字的偏移量來訪問,或者根本不需要偏移量。

這會使代碼更緊湊,方便更有效地使用代碼緩存。因此,建議在結(jié)構(gòu)或類聲明中,大數(shù)組和其他大對象排在最后,最常用的數(shù)據(jù)成員排在前面。如果不能在前128個字節(jié)內(nèi)包含所有數(shù)據(jù)成員,則將最常用的成員放在前128個字節(jié)中。

通過上面兩個小知識點可以使得將結(jié)構(gòu)體設(shè)計的更小,訪問數(shù)據(jù)成員的速度更快,但是這有時往往會犧牲一些可讀性,比如這種結(jié)構(gòu)體:

struct S {

int deskA;

double deskB;

bool deskC;

int chairA;

double chairB;

bool chairC;

};

可能這樣修改后結(jié)構(gòu)體會更?。?/p>

struct S {

int deskA;

int chairA;

double deskB;

double chairB;

bool deskC;

bool chairC;

};

但是我們一般情況下貌似希望同類的字段放在一起,這樣代碼可讀性更高一些,易于讀懂代碼。至于這種結(jié)構(gòu)體具體需不需要重新排序,那就需要大家自己權(quán)衡啦。

小總結(jié):

注意內(nèi)存對齊;

128是個檻,常用的數(shù)據(jù)成員可考慮放在前128字節(jié)中,不常用的或大的數(shù)據(jù)成員可考慮放在后面;

注重性能優(yōu)化的同時也需要權(quán)衡一下代碼的可讀性。

打完收工。

責(zé)任編輯:haq

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 存儲器
    +關(guān)注

    關(guān)注

    39

    文章

    7738

    瀏覽量

    171652
  • 內(nèi)存
    +關(guān)注

    關(guān)注

    9

    文章

    3209

    瀏覽量

    76358
  • 結(jié)構(gòu)體
    +關(guān)注

    關(guān)注

    1

    文章

    131

    瀏覽量

    11371

原文標(biāo)題:如何設(shè)計結(jié)構(gòu)體

文章出處:【微信號:gh_3980db2283cd,微信公眾號:開關(guān)電源芯片】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    10個例子代碼,C語言結(jié)構(gòu)的高級

    當(dāng)涉及到C語言結(jié)構(gòu)的高級**時,有很多有趣和強(qiáng)大的技巧可以應(yīng)用。下面是10個例子代碼,每個例子都使用了不同的高級結(jié)構(gòu)技術(shù),包括位字段、嵌
    發(fā)表于 01-05 06:32

    一個經(jīng)典的結(jié)構(gòu)和聯(lián)合體共用的實例

    Linux 中可以 使用 sizeof 進(jìn)行獲取,默認(rèn)為字節(jié)對齊的大小。 聯(lián)合體 聯(lián)合體的參數(shù)共享同一個內(nèi)存地址,所占的內(nèi)存大小完全是由聯(lián)合體中參數(shù)類型決定字長,然后數(shù)據(jù)共享,內(nèi)存共享等。 結(jié)構(gòu)和聯(lián)合體
    發(fā)表于 12-16 07:14

    結(jié)構(gòu)聲明與定義

    1、聲明 結(jié)構(gòu)的聲明使用struct關(guān)鍵字,如果我們想要把我們的學(xué)籍信息組織一下的話,可以這樣表示: struct Info { unsigned long identifier;//學(xué)號
    發(fā)表于 12-11 07:52

    typedef結(jié)構(gòu)使用

    雖然結(jié)構(gòu)的出現(xiàn)能夠讓我們有一個更科學(xué)的數(shù)據(jù)結(jié)構(gòu)來管理數(shù)據(jù),但是每次使用結(jié)構(gòu)都需要struct
    發(fā)表于 12-08 07:04

    為什么不建議用匿名結(jié)構(gòu)

    說起匿名結(jié)構(gòu),想必大家第一感覺就是看著好高大上的名字,但實際上也就那樣。 typedef struct { union { struct { uint8_t bit_0:1
    發(fā)表于 12-04 07:39

    modbus消息幀的模塊化架構(gòu)介紹

    01/02/03/04 讀取線圈/輸入/保持寄存器 數(shù)據(jù)寫入 05/06/15/16 寫入單個/多個寄存器 診斷類 08/0B/0E 設(shè)備診斷/異常報告 3. 數(shù)據(jù)字段:操作參數(shù)的載體 數(shù)據(jù)字段
    發(fā)表于 11-17 08:15

    C語言結(jié)構(gòu)使用

    有時候需要將不同類型的數(shù)據(jù)組合為一個整體,以便于引用。例如,一名學(xué)生有學(xué)號、姓名、性別、年齡等屬性,如果針對每個屬性都單獨(dú)定義一個變量,那么當(dāng)有多名學(xué)生時變量就難以分清。結(jié)構(gòu)就是用來管理不同類
    發(fā)表于 11-12 08:30

    NVMe高速傳輸之?dāng)[脫XDMA設(shè)計20: PCIe應(yīng)答模塊設(shè)計

    所示。圖1TLP寫處理模塊結(jié)構(gòu)圖當(dāng)axis_cq總線中出現(xiàn)數(shù)據(jù)流傳輸時,應(yīng)答模塊首先對傳輸?shù)腡LP報頭的類型字段進(jìn)行解析,如果為存儲器寫請求則由寫處理模塊進(jìn)一步解析。寫處理模塊提取出TLP報頭的地址
    發(fā)表于 08-12 16:04

    NVMe高速傳輸之?dāng)[脫XDMA設(shè)計14: PCIe應(yīng)答模塊設(shè)計

    如圖1所示。 圖1TLP寫處理模塊結(jié)構(gòu)圖 當(dāng)axis_cq總線中出現(xiàn)數(shù)據(jù)流傳輸時,應(yīng)答模塊首先對傳輸?shù)腡LP報頭的類型字段進(jìn)行解析,如果為存儲器寫請求則由寫處理模塊進(jìn)一步解析。寫處理模塊提取
    發(fā)表于 08-04 16:44

    定義IO初始化結(jié)構(gòu)

    由上述IOPORT相關(guān)功能的枚舉類型我們可以知道,在對IOPORT模塊進(jìn)行初始化時需要根據(jù)情況配置它們。因此我們定義一個IOPORT初始化的結(jié)構(gòu)類型IOPORT_Init_t,它的成員包括了由上述所有枚舉類型所聲明的變量,因此該結(jié)構(gòu)
    的頭像 發(fā)表于 07-16 16:26 ?1407次閱讀

    智能AI面臨非結(jié)構(gòu)數(shù)據(jù)難題:IBM推出解決方案

    ,同時提供一個開放的混合數(shù)據(jù)基礎(chǔ)架構(gòu)和企業(yè)級的結(jié)構(gòu)化和非結(jié)構(gòu)數(shù)據(jù)管理。 智能AI面臨非結(jié)構(gòu)
    的頭像 發(fā)表于 07-02 09:40 ?518次閱讀

    滲壓計在混凝土結(jié)構(gòu)中的安裝指南

    在現(xiàn)代土木工程和巖土工程中,滲壓計是監(jiān)測混凝土結(jié)構(gòu)體內(nèi)孔隙水壓力變化的重要工具。南京峟思公司生產(chǎn)的滲壓計因其高精度和可靠性而被廣泛應(yīng)用于各種工程監(jiān)測項目中。一、滲壓計在混凝土結(jié)構(gòu)中的應(yīng)用價值滲壓計
    的頭像 發(fā)表于 05-28 10:55 ?596次閱讀
    滲壓計在混凝土<b class='flag-5'>結(jié)構(gòu)</b><b class='flag-5'>體</b>中的安裝指南

    使用USB控制中心通過FX3將數(shù)據(jù)傳輸?shù)紻SP,數(shù)據(jù)字丟失怎么解決?

    使用傳輸文件-輸出功能時, DMABuf1[0] 中的第一個數(shù)據(jù)字錯誤地為 0x0000,最后一個數(shù)據(jù)字 0x27FF 丟失。 有趣的是,如果我重新發(fā)送同一個文件,收到的第一個單詞就是之前丟失
    發(fā)表于 05-21 07:31

    程序設(shè)計與數(shù)據(jù)結(jié)構(gòu)

    《程序設(shè)計與數(shù)據(jù)結(jié)構(gòu)》重點闡述了三大方向內(nèi)容: 1. C語言學(xué)習(xí)中的痛點:針對當(dāng)前工程師在C語言學(xué)習(xí)中的痛點,如指針函數(shù)與函數(shù)指針,如何靈活應(yīng)用結(jié)構(gòu)等。從變量的三要素(變量的類型,變量的值和變量
    發(fā)表于 05-13 16:45

    C語言中結(jié)構(gòu)與聯(lián)合體的深度解析:內(nèi)存布局與應(yīng)用場景

    一、基礎(chǔ)概念與核心差異 1.1 結(jié)構(gòu)(Struct)的本質(zhì) **結(jié)構(gòu)是C語言中實現(xiàn)數(shù)據(jù)封裝的基石,其核心特征在于內(nèi)存獨(dú)立性。每個成員變量
    發(fā)表于 04-08 09:18