點(diǎn)擊上方「嵌入式大雜燴」,完全「星標(biāo)公眾號(hào)」第一時(shí)間查看精彩文章!類(lèi)型
C語(yǔ)言類(lèi)型
C的完全類(lèi)型分為:
對(duì)象類(lèi)型(char、int、類(lèi)型數(shù)組、完全指針、類(lèi)型結(jié)構(gòu)體等) 函數(shù)類(lèi)型 不完全類(lèi)型
什么是完全不完全類(lèi)型?
C/C++中不完全類(lèi)型有三種不同形式:void、未指定長(zhǎng)度的類(lèi)型數(shù)組以及具有非指定內(nèi)容的結(jié)構(gòu)和聯(lián)合。使用不完全類(lèi)型的完全指針或引用,不需要知道類(lèi)型的類(lèi)型全部?jī)?nèi)容。?比如:
我們常用以下方式聲明數(shù)組:
extern?int?array[];
此時(shí)的完全array就是一個(gè)不完全類(lèi)型的數(shù)組,一般這樣的數(shù)組聲明會(huì)放在.h中,而其定義放在.c中,在定義的時(shí)候在給出數(shù)組的具體長(zhǎng)度,若之后有需要改變數(shù)組的長(zhǎng)度時(shí),直接改.c里的就可以,對(duì)外的.h就保持原樣不用修改。
用數(shù)組來(lái)說(shuō)明可能還是有點(diǎn)不太好理解,下面我們用結(jié)構(gòu)體的例子來(lái)做說(shuō)明。
在此之前,我們先思考一個(gè)問(wèn)題,我們的結(jié)構(gòu)體實(shí)體是在頭文件中定義還是源文件中定義呢?
實(shí)際上,在頭文件、源文件中定義都可以
。
下面我們以一個(gè)動(dòng)態(tài)數(shù)組的管理
為例來(lái)做一些演示說(shuō)明。
在此之前,有必要認(rèn)識(shí)一下動(dòng)態(tài)數(shù)組(以下說(shuō)明來(lái)自百度百科):
動(dòng)態(tài)數(shù)組,是相對(duì)于靜態(tài)數(shù)組而言。靜態(tài)數(shù)組的長(zhǎng)度是預(yù)先定義好的,在整個(gè)程序中,一旦給定大小后就無(wú)法改變。而動(dòng)態(tài)數(shù)組則不然,它可以隨程序需要而重新指定大小。
動(dòng)態(tài)數(shù)組的內(nèi)存空間是從堆(heap)上分配(即動(dòng)態(tài)分配)的。是通過(guò)執(zhí)行代碼而為其分配存儲(chǔ)空間。當(dāng)程序執(zhí)行到這些語(yǔ)句時(shí),才為其分配。程序員自己負(fù)責(zé)釋放內(nèi)存。使用動(dòng)態(tài)數(shù)組的優(yōu)點(diǎn)是可以根據(jù)用戶(hù)需要,有效利用存儲(chǔ)空間。
(1)結(jié)構(gòu)體實(shí)體定義在頭文件中
比如我們本次的demo有如下三個(gè)文件:
此時(shí)dynamic_array.h
的內(nèi)容如下:
我們創(chuàng)建了一些接口函數(shù)來(lái)操作DA對(duì)象,我們希望他人可以使用我們的這些接口來(lái)操作數(shù)據(jù)。并且,一般我們使用其它人寫(xiě)的代碼時(shí),一般也是優(yōu)先找到相關(guān)頭文件,然后調(diào)用頭文件里提供的對(duì)外接口函數(shù)。
但是,從這個(gè)頭文件中,我們不僅僅看到了一些對(duì)外接口,還可以看到結(jié)構(gòu)體實(shí)體。于是乎,可能就有些人寫(xiě)出這樣的代碼:
命名有接口可以用,卻偏偏有人喜歡直接操作數(shù)據(jù),這是比較容易出錯(cuò)的做法。而且此時(shí)調(diào)用者推鍋的理由很充足:你暴露數(shù)據(jù)給我,我為什么不可以直接操控你的數(shù)據(jù),我就不喜歡用你提供的接口,咋的。。。
所以dynamic_array.h
的提供者還是得背鍋。
(2)結(jié)構(gòu)體實(shí)體定義在源文件中
為了不被推鍋,我們把我們的頭文件改為:
此時(shí),這里的dynamic_array_def結(jié)構(gòu)類(lèi)型就是一個(gè)不完全類(lèi)型。
我們把結(jié)構(gòu)體實(shí)體定義挪到源文件中,這時(shí)候調(diào)用者看不到dynamic_array_def里有什么數(shù)據(jù)了,間接地就可以強(qiáng)迫調(diào)用者使用我們提供的接口了。此時(shí)如果出問(wèn)題被推鍋,那我們也樂(lè)意接鍋,樂(lè)意查找問(wèn)題呀。
不完全類(lèi)型起到了數(shù)據(jù)隱藏的作用,用戶(hù)可以在頭文件中看到不包含具體細(xì)節(jié)的結(jié)構(gòu)體,具體細(xì)節(jié)及實(shí)現(xiàn)隱藏在.c中。因?yàn)槿绻嗉?xì)節(jié)暴露給用戶(hù),則用戶(hù)可能會(huì)依賴(lài)這些細(xì)節(jié),一旦細(xì)節(jié)發(fā)生變化,則用戶(hù)代碼可能會(huì)失效。
關(guān)于數(shù)據(jù)抽象與封裝也可查看往期筆記:C語(yǔ)言對(duì)象編程第一彈:封裝與抽象
最后,順便貼一下本demo工程完整代碼,有需要的朋友自取:
dynamic_array.h:
左右滑動(dòng)查看全部代碼>>>
#ifndef?__DYNAMIC_ARRAY_H
#define?__DYNAMIC_ARRAY_H
/*?結(jié)構(gòu)體“重命名”?*/
typedef?struct?dynamic_array?dynamic_array_def;
/*?初始化dynamic_array?*/
dynamic_array_def?*DA_Init(void);
/*?銷(xiāo)毀dynamic_array?*/
void?DA_Clean(dynamic_array_def?*pThis);
/*?設(shè)置dynamic_array長(zhǎng)度?*/
void?DA_SetSize(dynamic_array_def?*pThis,?unsigned?len);
/*?獲取dynamic_array長(zhǎng)度?*/
unsigned?DA_GetSize(dynamic_array_def?*pThis);
/*?設(shè)置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:
左右滑動(dòng)查看全部代碼>>>
#include?"dynamic_array.h"
#include?
/*?創(chuàng)建一個(gè)動(dòng)態(tài)數(shù)組結(jié)構(gòu)體模板?*/
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;
}
/*?銷(xiāo)毀dynamic_array?*/
void?DA_Clean(dynamic_array_def?*pThis)
{
????free(pThis->array);
????pThis->len?=?0;
????free(pThis);
}
/*?設(shè)置dynamic_array長(zhǎng)度?*/
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長(zhǎng)度?*/
size_t?DA_GetSize(dynamic_array_def?*pThis)
{
????return?pThis->len;
}
/*?設(shè)置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
左右滑動(dòng)查看全部代碼>>>
#include?
#include?
#include?"dynamic_array.h"
int?main(void)
{
????int?arr_elem?=?0;
????/*?初始化一個(gè)動(dòng)態(tài)數(shù)組?*/
?dynamic_array_def?*pArray?=?DA_Init();
????/*?設(shè)置數(shù)組長(zhǎng)度為10?*/
????DA_SetSize(pArray,?10);
????/*?給數(shù)組元素賦值?*/
????for?(int?i?=?0;?i?10;?i++)
????{
????????DA_SetValue(pArray,?i,?i);
????}
????/*?遍歷數(shù)組元素并打印?*/
????for?(int?i?=?0;?i?10;?i++)
????{
????????DA_GetValue(pArray,?i,?&arr_elem);
????????printf("%d?",?arr_elem);
????}
????
????/*?數(shù)組清理?*/
????DA_Clean(pArray);
????
????return?0;
}
編譯、運(yùn)行:
以上就是本次的分享,如有錯(cuò)誤,歡迎指出!感謝閱讀與分享~
相關(guān)參考:
https://blog.csdn.net/candcplusplus/article/details/38498707
http://www.voidcn.com/article/p-dsixnffi-k.html
https://www.cnblogs.com/new0801/p/6177080.html
周立功《程序設(shè)計(jì)與數(shù)據(jù)結(jié)構(gòu)》
猜你喜歡
一個(gè)不該被遺忘的打印輸出函數(shù)
分立式ARM+FPGA與ZYNQ SoC相比,有哪些好處?
1024G 嵌入式資源大放送!包括但不限于C/C++、單片機(jī)、Linux等。在公眾號(hào)聊天界面回復(fù)1024,即可免費(fèi)獲取!
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問(wèn)題,請(qǐng)聯(lián)系我們,謝謝!