當(dāng)前位置:首頁 > IT技術(shù) > 編程語言 > 正文

C/C++常識之?dāng)?shù)據(jù)類型
2021-10-28 15:20:24

基本數(shù)據(jù)類型

整型int,long,字符型char,浮點型float、double,常用的基本數(shù)據(jù)類型就這些。

結(jié)構(gòu)體

結(jié)構(gòu)體可以理解為開發(fā)者用已有的數(shù)據(jù)類型為原料組合成的數(shù)據(jù)類型。例如數(shù)組就是這樣的類型,數(shù)組其實就是我們開發(fā)者自己定義的一個數(shù)據(jù)類型,由多個相同數(shù)據(jù)類型的變量組合而所得,例如:

int a[maxSize];

上面這句話相當(dāng)于把maxSize個int型變量擺在一起,其中各個int型變量之間的關(guān)系由數(shù)組的下標(biāo)反映。

試想,如果我們想要定義這樣的數(shù)組,這個數(shù)組里面第一個變量是整形的,第二個變量是字符型的,第三個變量是浮點型的,此時就需要用到結(jié)構(gòu)體。

結(jié)構(gòu)體是系統(tǒng)提供給程序員制作新數(shù)據(jù)類型的一種機(jī)制,即可以用系統(tǒng)已有的不同的基本數(shù)據(jù)類型或用戶定義的結(jié)構(gòu)型,組合成用戶需要的復(fù)雜數(shù)據(jù)類型。

剛剛提到的那個“奇怪的數(shù)組”,可以用結(jié)構(gòu)體實現(xiàn)如下:

typedef struct
{
    int a;
    char b;
    float c;
} MyType;

現(xiàn)有語句如下:

MyType a[3];

思考一下,上面這句話是什么意思呢?

顯然,上面這句話定義了一個數(shù)組,這個數(shù)組由3個MyType類型的元素組成。

因為前面已經(jīng)定義好了MyType類型的數(shù)據(jù)結(jié)構(gòu),MyType其實含有3個分量。

因此其實你可以把a(bǔ)類比為一個二維數(shù)組。

就好像下面這句話:

int b[3][3];

上面這句話定義了一個名字為b的二維數(shù)組,二維數(shù)組可以看成一個一維數(shù)組,其數(shù)組元素也是一個一維數(shù)組。

b中取第一個元素的第一個分量:

b[0][0]

a中取第一個元素的第一個分量:

a[0].a

指針

變量里面裝的是數(shù)據(jù)元素的內(nèi)容。

指針里面裝的是變量的地址。

通過指針可以找出變量在內(nèi)存中的位置。

指針對于每種數(shù)據(jù)類型都有特定的定義方法,有專門指向int的指針,也有專門指向float的指針...

對于每種變量,其指針的定義規(guī)則類似:

int *a ;
char *b ;
float *c ;
MyType *d ;

上面這段話表示:指向整形變量的指針a,指向字符型變量的指針b...

指針變量的定義只是在變量名前面多了一個*號

如果a是一個指針型變量,且這個指針型變量已經(jīng)指向了一個變量b,則a中存放的就是變量b的地址

*a

上面這句話表示取變量a中的內(nèi)容,其實就相當(dāng)于b

&b

上面這句話表示取變量b的地址

a = &b ;

上面這句話表示,將變量b的地址存放于指針a中,也可以叫做指針a指向b

鏈表結(jié)點的構(gòu)造

鏈表結(jié)點有2個域,即數(shù)據(jù)域和指針域。數(shù)據(jù)域存放數(shù)據(jù),指針域存放下一個結(jié)點的位置

鏈表結(jié)點的結(jié)構(gòu)型定義為:

typedef struct Node
{
    int data ;
    struct Node *next;
}Node ;

上面這段話的含義,請仔細(xì)理解一下

首先結(jié)構(gòu)型的名字為Node

因為組成此結(jié)構(gòu)體的成員中有一個指向和自己類型相同的變量的指針

并且內(nèi)部要用自己來定義這個指針,所以要寫成:

struct Node *next;

凡是結(jié)構(gòu)體a內(nèi)部含義指針b

并且b是用來存放和a類型相同的結(jié)構(gòu)體變量地址的指針類型(比如說鏈表的應(yīng)用場景,鏈表中結(jié)點的指針域指向的也是結(jié)點變量)

則在定義結(jié)構(gòu)體時,a的typedef struct語句之后要加上a這個結(jié)構(gòu)體的名字,比如上面的Node

從語法上來說,這里的兩個Node可以是不一樣的,編譯器也不會報錯,但是從程序的可讀性而言,最好這兩處的名稱是一樣的

C/C++常識之?dāng)?shù)據(jù)類型_結(jié)點

二叉樹結(jié)點的構(gòu)造

二叉樹的結(jié)點其實和鏈表的結(jié)點差不多,直接看代碼:

typedef stuct BTNode
{
    int data ;
    struct BTNode *lchid;
    struct BTNode *rchild;
}BTNode;

代碼不難理解,和剛剛鏈表結(jié)點的構(gòu)造差不多

當(dāng)然如果要寫得復(fù)雜點,還可以這樣寫:

typedef stuct BTNode
{
    int data ;
    struct BTNode *lchid;
    struct BTNode *rchild;
}BTNode,*btnode;

可以發(fā)現(xiàn),后面多寫了個*btnode,為什么要這樣寫呢?

考慮我們要定義一個結(jié)點指針p

如果用第一種定義方法(比較簡單的那個),我們需要這樣寫:

BTNode *p ;

如果你用第二種定義方法(比較復(fù)雜的那個,后面加了點東西)。我們可以這樣寫:

btnode p ;

兩種方法各有利弊:

簡單的方法利于理解,但是你定義結(jié)點的時候需要多寫一點,不容易搞混

復(fù)雜的方法寫的時候復(fù)雜,但是定義的時候可以少寫一點,容易搞混

下面介紹制作新結(jié)點的方法:

第一種方法這么寫

BTNode BT ;

訪問的時候這樣寫(結(jié)構(gòu)體變量直接取其分量)

x = BT.data ;

該方法只用一句話就制作了一個結(jié)點

但是我們一般不會這么寫,而采用如下方法

第二種方法這么寫

BTNode *BT ;
BT = (BtNode*)malloc(sizeof(BTNode));

首先定義一個節(jié)點的額指針BT

然后使用函數(shù)malloc申請一個結(jié)點的內(nèi)存空間

最后讓BT指向這片內(nèi)存空間

其中malloc函數(shù)是系統(tǒng)提供的內(nèi)存分配函數(shù)

C/C++常識之?dāng)?shù)據(jù)類型_數(shù)組_02

當(dāng)然BT可以離開這個結(jié)點而轉(zhuǎn)向其他結(jié)點,所以說第二種方法比較靈活

訪問的時候這樣寫(指向結(jié)構(gòu)體變量的指針取結(jié)構(gòu)體的分量)

x = BT -> data ;

當(dāng)然你也可以這樣寫

x = (*BT).data ;

動態(tài)申請數(shù)組空間

剛剛是一次只申請一個結(jié)點,其實還有一次申請一組結(jié)點的方法

假設(shè)申請一個數(shù)組,數(shù)組內(nèi)的元素類型為int型,長度為n,當(dāng)然了,此處的int可以換成任意的數(shù)據(jù)類型,包括你自己定義的結(jié)構(gòu)體類型

int *p ;
p = (int *)malloc(n * sizeof(int)) ;

上述語句申請了一個,由p指向的,元素為int類型的,長度為n的動態(tài)數(shù)組

當(dāng)然p指向的是數(shù)組中第一個元素的地址

取元素的時候,和一般的靜態(tài)數(shù)組都是一樣的

對比

對比制作結(jié)點的第二種方法和動態(tài)申請數(shù)組空間的方法,其不同之處僅僅在于,sizeof運(yùn)算符前要乘以n

請注意sizeof是運(yùn)算符,不是函數(shù)

typedef

typedef就是給現(xiàn)有的數(shù)據(jù)類型起一個別名

比如typedef struct{...} TypeA

就是給struct{...}取一個別名TypeA

# define

給常量取個別名

給0、1取ERROR、OK以及maxSize等常數(shù)的別名上用的比較多

?

本文摘自 :https://blog.51cto.com/u

開通會員,享受整站包年服務(wù)立即開通 >