欧美在线专区-欧美在线伊人-欧美在线一区二区三区欧美-欧美在线一区二区三区-pornodoxxx中国妞-pornodoldoo欧美另类

什么是不完全類型?

[導讀]C/C++中不完全類型有三種不同形式:void、完全未指定長度的類型數組以及具有非指定內容的結構和聯合。使用不完全類型的完全指針或引用,不需要知道類型的類型全部內容。

點擊上方「嵌入式大雜燴」,完全「星標公眾號」第一時間查看精彩文章!類型

什么是不完全類型?

C語言類型

C的完全類型分為:

  • 對象類型(char、int、類型數組、完全指針、類型結構體等)
  • 函數類型
  • 不完全類型

什么是完全不完全類型?

C/C++中不完全類型有三種不同形式:void、未指定長度的類型數組以及具有非指定內容的結構和聯合。使用不完全類型的完全指針或引用,不需要知道類型的類型全部內容。?比如:

我們常用以下方式聲明數組:

extern?int?array[];

此時的完全array就是一個不完全類型的數組,一般這樣的數組聲明會放在.h中,而其定義放在.c中,在定義的時候在給出數組的具體長度,若之后有需要改變數組的長度時,直接改.c里的就可以,對外的.h就保持原樣不用修改。

用數組來說明可能還是有點不太好理解,下面我們用結構體的例子來做說明。

在此之前,我們先思考一個問題,我們的結構體實體是在頭文件中定義還是源文件中定義呢?

實際上,在頭文件、源文件中定義都可以

下面我們以一個動態數組的管理為例來做一些演示說明。

在此之前,有必要認識一下動態數組(以下說明來自百度百科):

動態數組,是相對于靜態數組而言。靜態數組的長度是預先定義好的,在整個程序中,一旦給定大小后就無法改變。而動態數組則不然,它可以隨程序需要而重新指定大小。

動態數組的內存空間是從堆(heap)上分配(即動態分配)的。是通過執行代碼而為其分配存儲空間。當程序執行到這些語句時,才為其分配。程序員自己負責釋放內存。使用動態數組的優點是可以根據用戶需要,有效利用存儲空間。

(1)結構體實體定義在頭文件中

比如我們本次的demo有如下三個文件:

此時dynamic_array.h的內容如下:

我們創建了一些接口函數來操作DA對象,我們希望他人可以使用我們的這些接口來操作數據。并且,一般我們使用其它人寫的代碼時,一般也是優先找到相關頭文件,然后調用頭文件里提供的對外接口函數。

但是,從這個頭文件中,我們不僅僅看到了一些對外接口,還可以看到結構體實體。于是乎,可能就有些人寫出這樣的代碼:

命名有接口可以用,卻偏偏有人喜歡直接操作數據,這是比較容易出錯的做法。而且此時調用者推鍋的理由很充足:你暴露數據給我,我為什么不可以直接操控你的數據,我就不喜歡用你提供的接口,咋的。。。

所以dynamic_array.h的提供者還是得背鍋。

(2)結構體實體定義在源文件中

為了不被推鍋,我們把我們的頭文件改為:

此時,這里的dynamic_array_def結構類型就是一個不完全類型。

我們把結構體實體定義挪到源文件中,這時候調用者看不到dynamic_array_def里有什么數據了,間接地就可以強迫調用者使用我們提供的接口了。此時如果出問題被推鍋,那我們也樂意接鍋,樂意查找問題呀。

不完全類型起到了數據隱藏的作用,用戶可以在頭文件中看到不包含具體細節的結構體,具體細節及實現隱藏在.c中。因為如果太多細節暴露給用戶,則用戶可能會依賴這些細節,一旦細節發生變化,則用戶代碼可能會失效。

關于數據抽象與封裝也可查看往期筆記:C語言對象編程第一彈:封裝與抽象

最后,順便貼一下本demo工程完整代碼,有需要的朋友自取:

dynamic_array.h:

左右滑動查看全部代碼>>>

#ifndef?__DYNAMIC_ARRAY_H
#define?__DYNAMIC_ARRAY_H

/*?結構體“重命名”?*/
typedef?struct?dynamic_array?dynamic_array_def;

/*?初始化dynamic_array?*/
dynamic_array_def?*DA_Init(void);

/*?銷毀dynamic_array?*/
void?DA_Clean(dynamic_array_def?*pThis);

/*?設置dynamic_array長度?*/
void?DA_SetSize(dynamic_array_def?*pThis,?unsigned?len);

/*?獲取dynamic_array長度?*/
unsigned?DA_GetSize(dynamic_array_def?*pThis);

/*?設置dynamic_array某元素的值?*/
int?DA_SetValue(dynamic_array_def?*pThis,?unsigned?index,?int?value);

/*?獲取dynamic_array某元素的值?*/
int?DA_GetValue(dynamic_array_def?*pThis,?unsigned?index,?int?*pValue);

#endif

dynamic_array.c:

左右滑動查看全部代碼>>>

#include?"dynamic_array.h"
#include?

/*?創建一個動態數組結構體模板?*/
struct?dynamic_array
{
????int?*array;
????unsigned?len;
};

/*?初始化dynamic_array?*/
dynamic_array_def?*DA_Init(void)
{
????dynamic_array_def?*pArray?=?malloc(sizeof(dynamic_array_def));

????pArray->array?=?NULL;
????pArray->len?=?0;
}

/*?銷毀dynamic_array?*/
void?DA_Clean(dynamic_array_def?*pThis)
{
????free(pThis->array);
????pThis->len?=?0;
????free(pThis);
}

/*?設置dynamic_array長度?*/
void?DA_SetSize(dynamic_array_def?*pThis,?size_t?len)
{
????pThis->len?=?len;
????pThis->array?=?(int*)realloc(pThis->array,?pThis->len*sizeof(int));
}

/*?獲取dynamic_array長度?*/
size_t?DA_GetSize(dynamic_array_def?*pThis)
{
????return?pThis->len;
}

/*?設置dynamic_array某元素的值?*/
int?DA_SetValue(dynamic_array_def?*pThis,?size_t?index,?int?value)
{
????if?(index?>?pThis->len)
????{
????????return?-1;
????}

????pThis->array[index]?=?value;
????return?0;
}

/*?獲取dynamic_array某元素的值?*/
int?DA_GetValue(dynamic_array_def?*pThis,?size_t?index,?int?*pValue)
{
????if?(index?>?pThis->len)
????{
????????return?-1;
????}

????*pValue?=?pThis->array[index];
????return?0;
}

main.c

左右滑動查看全部代碼>>>

#include?
#include?
#include?"dynamic_array.h"

int?main(void)
{
????int?arr_elem?=?0;

????/*?初始化一個動態數組?*/
?dynamic_array_def?*pArray?=?DA_Init();

????/*?設置數組長度為10?*/
????DA_SetSize(pArray,?10);

????/*?給數組元素賦值?*/
????for?(int?i?=?0;?i?????{
????????DA_SetValue(pArray,?i,?i);
????}

????/*?遍歷數組元素并打印?*/
????for?(int?i?=?0;?i?????{
????????DA_GetValue(pArray,?i,?&arr_elem);
????????printf("%d?",?arr_elem);
????}
????
????/*?數組清理?*/
????DA_Clean(pArray);
????
????return?0;
}

編譯、運行:

以上就是本次的分享,如有錯誤,歡迎指出!感謝閱讀與分享~

相關參考:

  1. https://blog.csdn.net/candcplusplus/article/details/38498707

  2. http://www.voidcn.com/article/p-dsixnffi-k.html

  3. https://www.cnblogs.com/new0801/p/6177080.html

  4. 周立功《程序設計與數據結構》

猜你喜歡

一個不該被遺忘的打印輸出函數

分立式ARM+FPGA與ZYNQ SoC相比,有哪些好處?


1024G 嵌入式資源大放送!包括但不限于C/C++、單片機、Linux等。在公眾號聊天界面回復1024,即可免費獲取!

免責聲明:本文內容由21ic獲得授權后發布,版權歸原作者所有,本平臺僅提供信息存儲服務。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯系我們,謝謝!

Popular articles

主站蜘蛛池模板: 国产91高清| 久久99国产精品久久99| 成人综合激情另类小说| 嗯啊用力视频| 福利一区二区三区视频在线观看 | 欧美人与物videos另类xxxxx| 欧美电影院一区二区三区| 女人脱裤子让男生桶的免费视频| 2019天堂精品视频在线观看| 国产一级一国产一级毛片| 国产精品多p对白交换绿帽| 日日爱影视| 国产国语对白露脸在线观看| 美女把尿口扒开让男人添| 亚洲国产成人久久一区www| 99香蕉国产精品偷在线观看| 日本1819| 蜜桃成熟时3之蜜桃仙子电影| 国产a级黄色片| 在厨房里挺进美妇雪臀| 男生肌肌捅女生肌肌视频| 高h全肉动漫在线观看| 波多野结衣办公室33分钟| 成品大香煮伊在2021一| 啊轻点灬大巴太粗太长了视频| 91久久偷偷做嫩草影院免| 97色伦图片97综合影院 | 丰满的寡妇3在线观看| 亚洲日产欧| 乱淫片免费影院观看| 月夜直播在线看片www| 亚洲宅男天堂| 波多野结衣护士无删减| 国产精品va在线观看一| 国产亚洲美女精品久久久久| 久久不见久久见免费影院www日本| 国产精品无码久久av| 国产**aa全黄毛片| 国产精品区免费视频| 女人扒开| 中文字幕在线资源|