色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

隱藏結構體成員的方法與問題

奈因PCB電路板設計 ? 來源:最后一個bug ? 作者:bug菌 ? 2021-08-11 10:18 ? 次閱讀

今天主要跟大家分享一種隱藏結構體成員的方法,很多地方也叫“不完全類型”,所以這里bug菌以更加通俗易懂的方式跟大家介紹下,并且談一談相關的一些問題。

1

引出話題

首先我們來看下面一個最簡單的例子:

參考代碼:

1/************filename:

App.h*************/ 2#ifndef __APP_H__ 3#define __APP_H__ 4 5 6typedef struct _tag_StObj stObj; 7struct _tag_StObj 8{ 9 int member1;

10 int member2;

11};

12 13//interface

14 15int sAdd(stObj *pObj); 16 17#endif 18 19/************filename: App.c*************/ 20#include “App.h” 21 22/**********************************

23 * Function : sAdd 24 * Note :加法函數,也是接口函數 25 * Author: bug菌

26 **********************************/ 27int sAdd(stObj *pObj) 28{ 29 return (pObj-》member1 + pObj-》member2); 30} 31 32/************filename: main.c*************/ 33#include 《stdio.h》 34#include

“。/App/App.h” 35 36int main(void) 37{ 38 stObj Obj; 39 Obj.member1 = 1;

40 Obj.member2 = 2; 41 42 printf(“result = %d ”,sAdd(&Obj)); 43 44 return 0; 45}

以上是三個文件中的內容,程序編譯通過,輸出結果為3。在main函數中均可以通過結構體定義變量,并且直接訪問其結構體內部的成員,而很多人覺得結構體作為一個對象不應該把其內部數據全部暴露出來供開放訪問,非常不利于內部實現細節的封裝和對象數據的安全性。那有什么辦法不允許外部訪問結構體成員呢?

2

不完全類型

“不完全類型”看起來很深奧的名字,主要還是翻譯問題吧,從字面上來說就是不那么完整的類型,我們知道像常規的char,int,float類型,要作為一個類型,那么平臺肯定為他們提供了所占據的內存大小和處理方式,而不完全類型幾乎沒有在定義的時候給出,比如沒有指定長度的數組array[],他也是一種不完全類型,雖然表示的是數組,可是你不知道它到底有多大,這樣編譯器就不能夠為其分配內存而定義報錯。下面修改下之前的程序,把結構體定義放到對應的app.c文件,而app.h中留下一個啥也不含的同名結構體“空殼”。

1/************filename: App.h*************/ 2#ifndef __APP_H__ 3#define __APP_H__ 4 5 6typedef struct _tag_StObj stObj;

7/*struct _tag_StObj 8{ 9 int member1;

10 int member2; 11};*/ 12 13//interface 14 15int sAdd(stObj *pObj);

16 17#endif 18 19/************filename: App.c*************/ 20#include “App.h” 21 22struct _tag_StObj 23{ 24 int member1; 25 int member2; 26};

27/********************************** 28 * Function : sAdd 29 * Note :加法函數,也是接口函數 30 * Author:

bug菌 31 **********************************/ 32int sAdd(stObj *pObj) 33{ 34 return (pObj-》member1 + pObj-》member2);

35} 36 37/************filename: main.c*************/ 38#include 《stdio.h》 39#include “。/App/App.h” 40 41int main(void) 42{ 43 stObj Obj;

44 Obj.member1 = 1; 45 Obj.member2 = 2;

46 47 printf(“result = %d ”,sAdd(&Obj)); 48 49 return 0; 50}

編譯結果:

此時編譯器會報一個error,表示不知道該結構體到底是多大,如果你要是問App.c文件里面不是定義了結構體成員嗎?怎么還會報錯?你需要看一下bug菌的往期精彩,C程序的編譯都是以源文件為單元展開的。

3

求助指針

把前面的main.c改改看能不能編譯通過:

1/************filename: main.c*************/ 2 3#include 《stdio.h》 4#include “。/App/App.h” 5 6int main(void) 7{ 8 stObj *Obj; 9 //Obj.member1 = 1;

10 //Obj.member2 = 2; 11 12 printf(“result = %d ”,sAdd(Obj)); 13 14 return 0; 15}

然而此時編譯通過:

當然上面程序語法沒問題,運行卻是有問題的,定義了一個野指針,一旦運行基本上都會奔潰。并且不能通過指針直接訪問結構體成員,因為這是一個不知道成員的結構體“空殼”,同樣sizeof也檢測不了大小。

那問題來了,為什么用結構體定義變量不行,而定義成指針卻可以呢?其實這個問題與bug菌之前談到的可以定義成void*指針變量,卻不能定義為void變量是相同的道理,因為指針的大小一般平臺和編譯器確定下來就基本確定下來了,它不依賴于所指向的對象類型,同樣void也是一個不完全類型。

4

隱藏結構體成員

現在遵循兩個原則:1、不能直接用不完全類型定義變量,可以定義指針:2、不能夠訪問其結構體內部成員,因為根本不知道。

參考代碼:

1/************filename: App.h*************/ 2#ifndef __APP_H__ 3#define __APP_H__ 4 5 6typedef struct _tag_StObj stObj;

7 8//interface 9stObj * sCreate(int member1,int member2); 10int sAdd(stObj *pObj);

11 12 13#endif 14 15/************filename: App.c*************/ 16#include “App.h” 17 18struct _tag_StObj 19{ 20 int member1; 21 int member2; 22}; 23 24/********************************** 25 * Function : sCreate 26 * Note :創建函數,也是接口函數 27 * Author: bug菌 28 **********************************/ 29stObj * sCreate(int member1,int member2) 30{ 31 static stObj staticObj;

32 33 staticObj.member1 = member1; 34 staticObj.member2 = member2; 35 36 return &staticObj; 37} 38 39 40/********************************** 41 * Function : sAdd 42 * Note :加法函數,也是接口函數 43 * Author: bug菌 44 **********************************/ 45int sAdd(stObj *pObj) 46{ 47 return (pObj-》member1 + pObj-》member2);

48} 49 50/************filename: main.c*************/ 51 52#include 《stdio.h》 53#include “。/App/App.h” 54 55int main(void) 56{ 57 stObj *Obj; 58 59 Obj = sCreate(3,5); //內部構造結構體

60 61 printf(“result = %d ”,sAdd(Obj)); //調用相應的接口 62 63 return 0; 64}

編譯成功,運行OK,結果如下:

那么不完全類型隱藏結構體成員的目的基本上就達到了,以后外部也是無法通過結構體變量直接訪問成員了,只能對象自身在相應的.c文件中定義對應的接口,然后聲明在對應的interface中供外部使用。

5

but

那么我們回過頭來想想這樣的不完全類型究竟做了啥?1)不允許外部訪問數據細節,因為這個類型不完整,編譯器把握不住~2)全程通過指針傳遞,本質上和void*差別不大,但是他可以進行類型的檢查,這樣代碼的數據意義更加的明確。

當我們使用不完全結構體類型,結構體所有的成員都變成了私有,即這一種封裝私有數據的方式,且均需要通過相應的接口函數訪問,確實一種好的面向對象的封裝方式。但是完全私有的封裝還是比較麻煩,還是要做到“公私分明”,函數調用也需要一定的開銷,就看工程師們怎么去平衡“性價比”了。

責任編輯:haq

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 嵌入式
    +關注

    關注

    5085

    文章

    19138

    瀏覽量

    305710
  • 結構體
    +關注

    關注

    1

    文章

    130

    瀏覽量

    10850

原文標題:如何隱藏"結構體對象"成員?

文章出處:【微信號:pcbgood,微信公眾號:奈因PCB電路板設計】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    結構成員的順序會影響結構的大小嗎

    相同的結構成員,如果把順序調整一下,會不會影響結構的大小? 答案是會的,這主要跟字節對齊有關。 比如這樣的
    的頭像 發表于 11-25 16:24 ?196次閱讀

    C語言和C++中結構的區別

    同樣是結構,看看在C語言和C++中有什么區別?
    的頭像 發表于 10-30 15:11 ?247次閱讀

    ota升級的庫中,結構upgrade_server_info中pespconn的作用是什么?

    check_cb; struct espconn *pespconn; }; 這個結構中已經有ip,port,pespconn這個結構
    發表于 07-12 06:33

    遞歸神經網絡結構形式主要分為

    結構形式。 Elman網絡 Elman網絡是一種基本的遞歸神經網絡結構,由Elman于1990年提出。其結構主要包括輸入層、隱藏層和輸出層,其中隱藏
    的頭像 發表于 07-05 09:32 ?559次閱讀

    請問esp-idf&vscode結構索引不到對應的成員如何解決?

    兄弟們,我用VSCode 初始化結構時,索引不到對應的成員,并且索引會出現不屬于結構體內的東西,有解決辦法嗎,球球了
    發表于 06-14 06:42

    esp32調試MQTT的程序,如何對.host初始化?

    esp_mqtt_client_config_t mqtt_cfg這個結構的時候,你們例程里面只初始化url,但是我在網上看到很多地方的參考程序都是初始化這些結構
    發表于 06-11 07:55

    你是否真的了解結構占用了多少字節?

    結構成員所占內存空間大小一般情況下,如果想知道結構成員的內存占用情況需要:1、先用
    的頭像 發表于 06-04 08:04 ?489次閱讀
    你是否真的了解<b class='flag-5'>結構</b><b class='flag-5'>體</b>占用了多少字節?

    嵌入式中C語言結構基本實現

    : ? ??在struct 中聲明了一個含有若干新成員的數據類型。 ????tag ?是結構標簽。 ????member-list ?是標準的變量定義,比如 int i; 或者 float f,或者其他
    的頭像 發表于 05-11 08:49 ?1056次閱讀
    嵌入式中C語言<b class='flag-5'>結構</b><b class='flag-5'>體</b>基本實現

    定義了一個結構,但是分配的地址不連續,為什么?

    定義了一個結構,但是分配的地址不連續,是KEIL的問題還是我的問題?
    發表于 04-26 08:12

    Go語言中的函數、方法與接口詳解

    Go 沒有類,不過可以為結構類型定義方法方法就是一類帶特殊的接收者參數的函數。方法接收者在它自己的參數列表內,位于 func 關鍵字和
    的頭像 發表于 04-23 16:21 ?850次閱讀

    C語言結構史上最詳細的講解【軟件干貨】

    struct結構數據類型 前言 我們知道,在C語言中有一些基本的數據類型,如?char?int?float?long?double?string(c99) 等等數據類型,他們可以表示一些事物
    的頭像 發表于 03-28 17:52 ?783次閱讀

    求助,請問一個結構如何全部定義到 __attribute__ 區域?

    請問一個結構如何全部定義到 __attribute__ 區域? 例如我這里涉及到一些高速計算的緩存,計劃將緩存數據存儲到 __attribute__ 區域。 三個結構 ,每個
    發表于 01-16 07:29

    經典 C 語言編程,結構和聯合體如何共用?

    結構 結構占用的內存大小,首先和編譯器的系統位數有關系,類似于CPU是 64 bits 還是 32 bits 的情形;其次,結構
    的頭像 發表于 01-11 18:24 ?1398次閱讀
    經典 C 語言編程,<b class='flag-5'>結構</b><b class='flag-5'>體</b>和聯合體如何共用?

    結構與指針的關系

    在C語言中,結構(Struct)是一種用戶自定義的數據類型,它允許您將不同類型的數據項組合在一起,以便形成一個更復雜的數據結構結構可以
    的頭像 發表于 01-11 08:00 ?1008次閱讀
    <b class='flag-5'>結構</b><b class='flag-5'>體</b>與指針的關系

    keil arm工程中結構1字節對齊如何實現

    在Keil Arm工程中,結構的對齊方式可以通過使用特定的編譯器指令或者關鍵字來實現。結構的對齊方式會直接影響結構
    的頭像 發表于 01-05 14:40 ?3848次閱讀
    主站蜘蛛池模板: 美女内射少妇一区二区四区| 好大好爽好深舒服死了| 亚洲人人为我我为人人| 使劲别停好大好深好爽动态图| 欧美午夜特黄AAAAAA片| 两个女人互添下身高潮自视频 | 美女也烦恼主题曲| 久久日本片精品AAAAA国产| 久草大| 久久AAAA片一区二区| 黄色a三级三级三级免费看| 精品一区二区免费视频蜜桃网| 精品成人在线视频| 久久6699精品国产人妻| 久久久久久极精品久久久| 快插我我好湿啊公交车上做| 空姐内射出白浆10p| 妹妹好色网| 欧美日韩高清一区| 人人干人人爽| 双腿打开揉弄高潮H苏安安秦慕深 双腿被绑成M型调教PLAY照片 | 国产真实女人一级毛片| 精品国产免费第一区二区| 久久精品美女| 男人天堂黄色| 日本午夜视频在线| 无限资源在线看影院免费观看| 亚洲第一色网站| 又粗又大又爽又黄的免费视频 | 果冻传媒剧情在线观看| 金瓶梅 快播| 麻豆蜜桃国语精品无码视频| 牛和人交videos欧美| 色戒床震视频片段| 亚洲AV午夜精品麻豆AV| 一区在线观看在线| 97影院午夜午夜伦不卡| 处破女免费播放| 国模沟沟一区二区三区| 麻豆无人区乱码| 人妻免费久久久久久久了|