1:結構體
結構體是一種自定義資料型別。宣告結構體時使用的關鍵字是struct,定義一種結構體的一般形式為:
struct 結構體名
結構體型別與基本型別一樣,都是從c語言中繼承下來的,但是c++結構體與c語言結構體是有區別的,c語言中沒有繼承、成員函式等概念,所以c語言中的結構體成員只能包含c語言中的資料型別,不能包含成員函式;但是c++語言卻不是。
c++中的結構體的使用方法和類的使用方法幾乎一樣,它包含this指標,可以繼承也可以被繼承;建立、銷毀和複製時均呼叫相應的構造、析構和複製建構函式;它包含虛表,可以被抽象化...但有兩點不同,其一,結構體的預設訪問許可權為public,而類中則是private;其二,結構體無法使用類模板。
2:資料型別別名——typedef
使用c++的typedef關鍵字可以將乙個資料型別的名稱賦予別名,也可以將已經存在的別名賦予您的名字,例如:
typedef flag int;
這樣,程式中的flag就可以作為int的資料型別來使用,例如:
flag a;
a實質上是int型別的資料,此時int型別的別名就是flag。
在宣告類或者結構體時使用typedef關鍵字,例如:
typedef class asdfgh
myclass,classa;
這樣就可以使宣告的類擁有myclass和classa兩個別名。
typedef的主要用途有如下兩個:
(1)定義很複雜的基本型別名稱,如函式指標int(*)(int i)。
typedef pfun int(*)(int i);
(2)使用其他人開發的型別時,使型別名符合自己的**習慣(規範)。
tpedef關鍵字具有作用域。範圍是別名宣告所在的區域(包含命名空間)。
2:malloc函式
malloc函式是一種分配長度為num_bytes位元組的記憶體塊的函式,可以向系統申請分配指定size個位元組的記憶體空間。malloc的全稱是memory allocation,中文叫動態記憶體分配,當無法知道記憶體具體位置的時候,想要繫結真正的記憶體空間,就需要用到動態的分配記憶體。
返回型別是 void* 型別。void* 表示未確定型別的指標。c,c++規定,void* 型別可以通過型別轉換強制轉換為任何其它型別的指標。
(1)原型:
extern void *malloc(unsigned int num_bytes);
(2)標頭檔案:
#include
或者
#include
(3)函式宣告:
void *malloc(size_t size);
備註:void* 表示未確定型別的指標,void *可以指向任何型別的資料,更明確的說是指申請記憶體空間時還不知道使用者是用這段空間來儲存什麼型別的資料(比如是char還是int或者其他資料型別)。
(4)返回:
如果分配成功則返回指向被分配記憶體的指標(此儲存區中的初始值不確定),否則返回空指標null。當記憶體不再使用時,應使用free()函式將記憶體塊釋放。函式返回的指標一定要適當對齊,使其可以用於任何資料物件。
(5)說明:
關於該函式的原型,在以前malloc返回的是char型指標,新的ansic標準規定,該函式返回為void型指標,因此必要時要進行型別轉換。
(6)與new的不同
從本質上來說,malloc(linux上具體實現可以參考man malloc,glibc通過brk()&mmap()實現)是libc裡面實現的乙個函式,如果在source code中沒有直接或者間接include過stdlib.h,那麼gcc就會報出error:『malloc』 was not declared in this scope。如果生成了目標檔案(假定動態鏈結malloc),如果執行平台上沒有libc(linux平台,手動指定ld_library_path到乙個空目錄即可),或者libc中沒有malloc函式,那麼會在執行時(run-time)出錯。new則不然,是c++的關鍵字,它本身不是函式。new不依賴於標頭檔案,c++編譯器就可以把new編譯成目標**(g++4.6.3會向目標中插入_znwm這個函式,另外,編譯器還會根據引數的型別,插入相應的建構函式)。
在使用上,malloc 和 new 至少有兩個不同: new 返回指定型別的指標,並且可以自動計算所需要大小。比如:
int *p;
p = new int;
//返回型別為int *型別(整數型指標),分配大小為sizeof(int);
或
int *parr;
parr = new int[100];
//返回型別為int *型別(整數型指標),分配大小為sizeof(int) * 100;
而 malloc 則必須要由我們計算位元組數,並且在返回後強行轉換為實際型別的指標。
int *p;
p = (int*)malloc(sizeof(int) * 128);
//分配128個(可根據實際需要替換該數值)整型儲存單元,
//並將這128個連續的整型儲存單元的首位址儲存到指標變數p中
double *pd = (double*)malloc(sizeof(double) * 12);
//分配12個double型儲存單元,
//並將首位址儲存到指標變數pd中
第一、malloc 函式返回的是 void * 型別。
對於c++,如果你寫成:p = malloc (sizeof(int)); 則程式無法通過編譯,報錯:「不能將 void* 賦值給 int * 型別變數」。所以必須通過 (int *) 來將強制轉換。而對於c,沒有這個要求,但為了使c程式更方便的移植到c++中來,建議養成強制轉換的習慣。
第二、函式的實參為 sizeof(int) ,用於指明乙個整型資料需要的大小。
在規範的程式中我們有必要按照這樣的格式去使用malloc及free:
type *p;
if(null == (p = (type*)malloc(sizeof(type))))
/*請使用if來判斷,這是有必要的*/
.../*其它***/
free(p);
p = null;/***上這句*/
malloc 也可以達到 new 的效果,申請出一段連續的記憶體,方法無非是指定你所需要記憶體大小。比如想分配100個int型別的空間:
int *p = (int*)malloc(sizeof(int) * 100);
//分配可以放得下100個整數的記憶體空間。
另外有一點不能直接看出的區別是,malloc 只管分配記憶體,並不能對所得的記憶體進行初始化,所以得到的一片新記憶體中,其值將是隨機的。
除了分配及最後釋放的方法不一樣以外,通過malloc或new得到指標,在其它操作上保持一致。
(7)工作機制
malloc函式的實質體現在,它有乙個將可用的記憶體塊連線為乙個長長的列表的所謂空閒鍊錶。呼叫malloc函式時,它沿連線表尋找乙個大到足以滿足使用者請求所需要的記憶體塊。然後,將該記憶體塊一分為二(一塊的大小與使用者請求的大小相等,另一塊的大小就是剩下的位元組)。接下來,將分配給使用者的那塊記憶體傳給使用者,並將剩下的那塊(如果有的話)返回到連線表上。呼叫free函式時,它將使用者釋放的記憶體塊連線到空閒鏈上。到最後,空閒鏈會被切成很多的小記憶體片段,如果這時使用者申請乙個大的記憶體片段,那麼空閒鏈上可能沒有可以滿足使用者要求的片段了。於是,malloc函式請求延時,並開始在空閒鏈上翻箱倒櫃地檢查各記憶體片段,對它們進行整理,將相鄰的小空閒塊合併成較大的記憶體塊。如果無法獲得符合要求的記憶體塊,malloc函式會返回null指標,因此在呼叫malloc動態申請記憶體塊時,一定要進行返回值的判斷。
3:程式設計實現乙個單鏈表的建立,**如下:
//#include "stdafx.h"
#include typedef struct node//定義鍊錶結構體
node;
node *create()//建立單鏈表
else
q->next = null;/*尾結點的後繼指標為null(空)*/
}return head;
}int length(node *head)
return len;
}void print(node *head)
}int main()
view code
執行結果:
收藏
資料結構 程式設計實現乙個單鏈表的列印
include stdafx.h include include typedef struct lnode lnode 上面只是定義了乙個結構體型別,並未實際分配記憶體空間 只有定義了變數才分配記憶體空間 lnode creat int n else p2 next null 尾結點的後繼指標為nu...
資料結構 程式設計實現乙個單鏈表節點的插入
1 向鍊錶中某個位置 第pos個節點 之後插入節點,這裡分別插入到鍊錶首部 插入到鍊錶中間,以及鍊錶尾端3個位置。如下 include stdafx.h include include using namespace std typedef struct node 定義鍊錶結構體 node node...
資料結構 實現乙個單鏈表的逆置
1 這是乙個經常被問到的面試題,也是乙份非常基礎的問題。比如乙個鍊錶是這樣的 1 2 3 4 5通過逆置後成為5 4 3 2 1。include stdafx.h include include using namespace std typedef struct node 定義鍊錶結構體 node...