基本數(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可以是不一樣的,編譯器也不會報錯,但是從程序的可讀性而言,最好這兩處的名稱是一樣的
二叉樹結(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ù)
當(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