chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

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

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

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

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

奈因PCB電路板設計 ? 來源:最后一個bug ? 作者:bug菌 ? 2021-08-11 10:18 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

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

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 :加法函數(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}

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

2

不完全類型

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

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

然而此時編譯通過:

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

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

4

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

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

參考代碼:

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)用相應的接口 62 63 return 0; 64}

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

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

5

but

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

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

責任編輯:haq

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

    關(guān)注

    5188

    文章

    20187

    瀏覽量

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

    關(guān)注

    1

    文章

    131

    瀏覽量

    11304

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

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

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

掃碼添加小助手

加入工程師交流群

    評論

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

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

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

    無數(shù)據(jù)域雙向鏈表的代碼

    印鏈表內(nèi)容的函數(shù)中,通過 offsetof 宏獲取 Data 結(jié)構(gòu)中 listNode 成員的偏移量,從而得到節(jié)點所在的地址,進而訪問節(jié)點中存儲的數(shù)據(jù)。 通過這個示例,我們可以看到如何使用無數(shù)據(jù)域雙向鏈表進行插入和訪問操作,
    發(fā)表于 12-11 06:56

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

    雖然結(jié)構(gòu)的出現(xiàn)能夠讓我們有一個更科學的數(shù)據(jù)結(jié)構(gòu)來管理數(shù)據(jù),但是每次使用結(jié)構(gòu)都需要struct...,未免顯得有些冗長和麻煩。有了type
    發(fā)表于 12-08 07:04

    共用聲明

    共用也稱聯(lián)合體。 和結(jié)構(gòu)還是有點像: union 共用名稱 { 成員1; 成員2
    發(fā)表于 12-05 07:24

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

    : invalid use of ‘struct data_def::::value_bit’ 有可能有方法可以設置 gcc 編譯支持匿名結(jié)構(gòu),但是魚鷹也不想深究,改了就是。 因此,為了代碼的通用性
    發(fā)表于 12-04 07:39

    C語言的編程技巧

    1、宏定義使用do{...}while(0)?:當宏定義中包含多條語句時,使用do{...}while(0)可以避免語句嵌套問題,確保宏的獨立性。? ?2、靈活數(shù)組成員?:C99標準允許結(jié)構(gòu)的最后
    發(fā)表于 11-27 06:46

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

    型的數(shù)據(jù)組合。 結(jié)構(gòu)的聲明與定義 結(jié)構(gòu)的聲明一般形式為: c struct 結(jié)構(gòu)名{
    發(fā)表于 11-12 08:30

    can_sample例程,rxmsg.hdr = -1;語句報錯如何解決?

    使用官方CAN_sample例程編譯,cubemx已經(jīng)配置好CAN引腳,menuconfig也已經(jīng)打開相關(guān)接口,但編譯時報錯,顯示結(jié)構(gòu) rt_can_msg結(jié)構(gòu)中沒有hdr這個
    發(fā)表于 09-24 07:05

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

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

    材料導熱系數(shù)測試方法及應用

    材料特殊的半固態(tài)特性(易流動、易變形、接觸熱阻大)給測試帶來挑戰(zhàn)。本文將系統(tǒng)介紹適用于膏材料的導熱系數(shù)測試方法。一、實驗步驟1、實驗設備DZDR-S導熱系數(shù)測
    的頭像 發(fā)表于 06-16 14:35 ?504次閱讀
    膏<b class='flag-5'>體</b>材料導熱系數(shù)測試<b class='flag-5'>方法</b>及應用

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

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

    GLAD應用:全息光柵模擬

    成像的衍射元件,可以使得三維物場信息按照光學斷層切片方式逐片地重構(gòu)成像,不同的斷層切片對應于三維物空間上軸向的不同位置。因此,采用全息成像方法既可以研究靜態(tài)物體的高度與外形輪廓的變化,以及半透明物體
    發(fā)表于 05-15 09:32

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

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

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

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

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

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