欧美在线专区-欧美在线伊人-欧美在线一区二区三区欧美-欧美在线一区二区三区-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

主站蜘蛛池模板: loveme枫と铃樱花动漫| 美女脱了内裤打开腿让你桶爽| 黄色三级理沦片| 久久精品国产99久久久| 黄色一级大片| 亚洲偷自拍另类图片二区| 被女同桌调教成鞋袜奴脚奴| 黑人在线观看| 蜜挑成熟时k8经典网| 免费观看女人与狥交视频在线| 欧美性猛交| 中国内地毛片免费高清| 日韩毛片高清在线看| 美女被到爽羞羞漫画| 被夫の上司持久侵犯奈奈美| 久久国产精品二国产精品| а√在线地址最新版| 中文字幕制服诱惑| 国产一区美女视频| 亚洲国产精品综合久久网络| 里番牝教师~淫辱yy608| 毛片aa| 日本人与黑人videos系列| 韩国三级最新理论电影| 亚洲女初尝黑人巨高清| 久久夜色精品国产亚洲| 一级毛片免费播放男男| 一级黄影| 中韩日产字幕2021| 免费啪啪社区免费啪啪手机版| 欧美日韩色黄大片在线视频| 午夜网站免费版在线观看| 国产精品欧美一区二区三区不卡| 天下第一社区视频welcome| 国产精品一区二区久久不卡| 日本理论在线| 久久九九99热这里只有精品| 日韩毛片电影| 久久精品a亚洲国产v高清不卡| 欧美性视频18~19| 女人张开腿让男人捅爽|