在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

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

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

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

隱藏結(jié)構(gòu)體成員的方法與問題

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

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

1

引出話題

首先我們來看下面一個(gè)最簡(jiǎn)單的例子:

參考代碼:

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 :加法函數(shù),也是接口函數(shù) 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}

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

2

不完全類型

“不完全類型”看起來很深?yuàn)W的名字,主要還是翻譯問題吧,從字面上來說就是不那么完整的類型,我們知道像常規(guī)的char,int,float類型,要作為一個(gè)類型,那么平臺(tái)肯定為他們提供了所占據(jù)的內(nèi)存大小和處理方式,而不完全類型幾乎沒有在定義的時(shí)候給出,比如沒有指定長(zhǎng)度的數(shù)組array[],他也是一種不完全類型,雖然表示的是數(shù)組,可是你不知道它到底有多大,這樣編譯器就不能夠?yàn)槠浞峙鋬?nèi)存而定義報(bào)錯(cuò)。下面修改下之前的程序,把結(jié)構(gòu)體定義放到對(duì)應(yīng)的app.c文件,而app.h中留下一個(gè)啥也不含的同名結(jié)構(gòu)體“空殼”。

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 :加法函數(shù),也是接口函數(shù) 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}

編譯結(jié)果:

此時(shí)編譯器會(huì)報(bào)一個(gè)error,表示不知道該結(jié)構(gòu)體到底是多大,如果你要是問App.c文件里面不是定義了結(jié)構(gòu)體成員嗎?怎么還會(huì)報(bào)錯(cuò)?你需要看一下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}

然而此時(shí)編譯通過:

當(dāng)然上面程序語法沒問題,運(yùn)行卻是有問題的,定義了一個(gè)野指針,一旦運(yùn)行基本上都會(huì)奔潰。并且不能通過指針直接訪問結(jié)構(gòu)體成員,因?yàn)檫@是一個(gè)不知道成員的結(jié)構(gòu)體“空殼”,同樣sizeof也檢測(cè)不了大小。

那問題來了,為什么用結(jié)構(gòu)體定義變量不行,而定義成指針卻可以呢?其實(shí)這個(gè)問題與bug菌之前談到的可以定義成void*指針變量,卻不能定義為void變量是相同的道理,因?yàn)橹羔樀拇笮∫话闫脚_(tái)和編譯器確定下來就基本確定下來了,它不依賴于所指向的對(duì)象類型,同樣void也是一個(gè)不完全類型。

4

隱藏結(jié)構(gòu)體成員

現(xiàn)在遵循兩個(gè)原則:1、不能直接用不完全類型定義變量,可以定義指針:2、不能夠訪問其結(jié)構(gòu)體內(nèi)部成員,因?yàn)楦静恢馈?/p>

參考代碼:

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 :創(chuàng)建函數(shù),也是接口函數(shù) 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 :加法函數(shù),也是接口函數(shù) 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); //內(nèi)部構(gòu)造結(jié)構(gòu)體

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

編譯成功,運(yùn)行OK,結(jié)果如下:

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

5

but

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

當(dāng)我們使用不完全結(jié)構(gòu)體類型,結(jié)構(gòu)體所有的成員都變成了私有,即這一種封裝私有數(shù)據(jù)的方式,且均需要通過相應(yīng)的接口函數(shù)訪問,確實(shí)一種好的面向?qū)ο蟮姆庋b方式。但是完全私有的封裝還是比較麻煩,還是要做到“公私分明”,函數(shù)調(diào)用也需要一定的開銷,就看工程師們?cè)趺慈テ胶狻靶詢r(jià)比”了。

責(zé)任編輯:haq

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

    關(guān)注

    5121

    文章

    19416

    瀏覽量

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

    關(guān)注

    1

    文章

    130

    瀏覽量

    10997

原文標(biāo)題:如何隱藏"結(jié)構(gòu)體對(duì)象"成員?

文章出處:【微信號(hào):pcbgood,微信公眾號(hào):奈因PCB電路板設(shè)計(jì)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

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

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

    聯(lián)想一機(jī)B5040拆解方法

    本文詳細(xì)記錄著聯(lián)想一機(jī)B5040的拆卸方法
    發(fā)表于 03-20 18:04 ?0次下載

    結(jié)構(gòu)成員的順序會(huì)影響結(jié)構(gòu)的大小嗎

    相同的結(jié)構(gòu)成員,如果把順序調(diào)整一下,會(huì)不會(huì)影響結(jié)構(gòu)的大小? 答案是會(huì)的,這主要跟字節(jié)對(duì)齊有關(guān)。 比如這樣的
    的頭像 發(fā)表于 11-25 16:24 ?437次閱讀

    C語言和C++中結(jié)構(gòu)的區(qū)別

    同樣是結(jié)構(gòu),看看在C語言和C++中有什么區(qū)別?
    的頭像 發(fā)表于 10-30 15:11 ?569次閱讀

    帶你認(rèn)識(shí)貼片一成型電感的材料結(jié)構(gòu)

    貼片一成型電感(也被稱為模壓電感)是一種具有特殊結(jié)構(gòu)和材料組成的電子元件。其材料結(jié)構(gòu)主要包括以下幾個(gè)方面: 一、主要材料 1. 金屬粉末 核心材料:一成型電感的主要材料是金屬粉末,
    的頭像 發(fā)表于 08-07 16:01 ?796次閱讀
    帶你認(rèn)識(shí)貼片一<b class='flag-5'>體</b>成型電感的材料<b class='flag-5'>結(jié)構(gòu)</b>

    成型電感表面開裂的解決方法

    電子發(fā)燒友網(wǎng)站提供《一成型電感表面開裂的解決方法.docx》資料免費(fèi)下載
    發(fā)表于 07-30 14:22 ?0次下載

    ota升級(jí)的庫(kù)中,結(jié)構(gòu)upgrade_server_info中pespconn的作用是什么?

    check_cb; struct espconn *pespconn; }; 這個(gè)結(jié)構(gòu)中已經(jīng)有ip,port,pespconn這個(gè)結(jié)構(gòu)
    發(fā)表于 07-12 06:33

    遞歸神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)形式主要分為

    結(jié)構(gòu)形式。 Elman網(wǎng)絡(luò) Elman網(wǎng)絡(luò)是一種基本的遞歸神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu),由Elman于1990年提出。其結(jié)構(gòu)主要包括輸入層、隱藏層和輸出層,其中隱藏
    的頭像 發(fā)表于 07-05 09:32 ?776次閱讀

    遞歸神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu)、特點(diǎn)、優(yōu)缺點(diǎn)及適用場(chǎng)景

    識(shí)別、時(shí)間序列分析等領(lǐng)域有著廣泛的應(yīng)用。本文將詳細(xì)介紹遞歸神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu)、特點(diǎn)、優(yōu)缺點(diǎn)以及適用場(chǎng)景。 一、遞歸神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu) 基本結(jié)構(gòu) 遞歸神經(jīng)網(wǎng)絡(luò)的基本結(jié)構(gòu)包括輸入層、
    的頭像 發(fā)表于 07-04 14:52 ?2160次閱讀

    請(qǐng)問esp-idf&amp;vscode結(jié)構(gòu)索引不到對(duì)應(yīng)的成員如何解決?

    兄弟們,我用VSCode 初始化結(jié)構(gòu)時(shí),索引不到對(duì)應(yīng)的成員,并且索引會(huì)出現(xiàn)不屬于結(jié)構(gòu)體內(nèi)的東西,有解決辦法嗎,球球了
    發(fā)表于 06-14 06:42

    esp32調(diào)試MQTT的程序,如何對(duì).host初始化?

    esp_mqtt_client_config_t mqtt_cfg這個(gè)結(jié)構(gòu)的時(shí)候,你們例程里面只初始化url,但是我在網(wǎng)上看到很多地方的參考程序都是初始化這些結(jié)構(gòu)
    發(fā)表于 06-11 07:55

    你是否真的了解結(jié)構(gòu)占用了多少字節(jié)?

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

    嵌入式中C語言結(jié)構(gòu)基本實(shí)現(xiàn)

    : ? ??在struct 中聲明了一個(gè)含有若干新成員的數(shù)據(jù)類型。 ????tag ?是結(jié)構(gòu)標(biāo)簽。 ????member-list ?是標(biāo)準(zhǔn)的變量定義,比如 int i; 或者 float f,或者其他
    的頭像 發(fā)表于 05-11 08:49 ?1326次閱讀
    嵌入式中C語言<b class='flag-5'>結(jié)構(gòu)</b><b class='flag-5'>體</b>基本實(shí)現(xiàn)

    定義了一個(gè)結(jié)構(gòu),但是分配的地址不連續(xù),為什么?

    定義了一個(gè)結(jié)構(gòu),但是分配的地址不連續(xù),是KEIL的問題還是我的問題?
    發(fā)表于 04-26 08:12

    Go語言中的函數(shù)、方法與接口詳解

    Go 沒有類,不過可以為結(jié)構(gòu)類型定義方法方法就是一類帶特殊的接收者參數(shù)的函數(shù)。方法接收者在它自己的參數(shù)列表內(nèi),位于 func 關(guān)鍵字和
    的頭像 發(fā)表于 04-23 16:21 ?1054次閱讀
    主站蜘蛛池模板: 日本人69xxxxxxx69 | 色婷婷色综合 | 国产女人18毛片水真多18精品 | 国产成人精品日本亚洲直接 | 天天添天天射 | 黄色一级片视频 | 日本不卡视频一区二区 | 色多多福利网站 | 两性午夜欧美高清做性 | 五月婷婷婷婷婷 | 青楼社区51在线视频视频 | 久久伊人色 | 萝l在线精品社区资源 | 欧美一卡2卡三卡4卡5卡免费观看 | 欧美一级片免费观看 | 婷婷在线免费观看 | 中文字幕视频二区 | 在线天堂中文新版www | 两性色午夜视频免费网 | 业余性自由色xxxx视频 | 亚洲 欧美 日韩 在线 中文字幕 | 天天爽夜夜爽每晚高澡 | 中日韩欧美在线观看 | 日本最顶级丰满的aⅴ艳星 日本最好的免费影院 | 在线播放免费 | www.毛片.com| 一区二区三区中文国产亚洲 | 国产怡红院 | 日日日天天射天天干视频 | 2019天天操夜夜操 | 亚洲欧洲一区二区三区在线观看 | 性色欧美 | 四虎影午夜成年免费精品 | 色www| 久久久久国产免费 | 久综合网 | 亚洲综合色一区二区三区小说 | 永久免费精品影视网站 | 天堂资源8中文最新版在线 天堂资源地址在线 | 欧美午夜精品久久久久久黑人 | 两性色午夜视频免费老司机 |