跟著dsaa in c寫**,總結起來各種資料結構大概都是這個套路:
首先是定義:
typedef
struct ***xx
***
然後分配空間,malloc(sizeof(***))
對於用到陣列來儲存資料元素的,還要額外給陣列分配空間,比如佇列:
q->array = malloc(sizeof(int) * max);
最後用完之後一定要記得free!
typedef
struct imgstruct
image;
image *
image_import
(char
*img_name)
}return img;
}
在main函式中只需要這樣既可:
image *src;
src =
image_import
("demo.bmp"
);
最後是free,設定null是防止懸空指標:
void
image_free
(image *img)
強調一下懸空指標的問題,參考懸空指標(dangling pointer)避免方法:
什麼是懸空指標?btw,dsaa中資料結構的各種函式多是傳指標作為引數,傳值的方法當然也可以,兩者的區別可以參考c語言 結構體傳值與傳址分析:乙個指標所指的記憶體被釋放後,這個指標就被懸空了。
懸空指標的危害?
訪問懸空指標,結果隨機。可能導致程式功能不正常,也可能導致程式崩潰。如果受到影響的是其它功能,問題通常很難定位。
如何避免懸空指標?
基本思路:在釋放一塊記憶體時,將指向這塊記憶體的指標變數設定為null。訪問指標變數前,先判斷是否為null。
高階:當有多個指標變數都指向同一塊記憶體時,釋放這塊記憶體時,需要將所有指標變數的值都置為null,這需要維護所有指向這塊記憶體的指標變數的資訊,但是這種方式開銷大,所以通常很少使用。使用頻率不是非常高的物件,可以在使用前先根據id等索引查詢,如果找不到,則不要使用。如果有使用者時,不能釋放這塊記憶體,我們可以使用引用計數,只有當引用計數為0時,才真正釋放記憶體,否則,只是引用計數減1。
結構體物件作為引數時,編譯器對其進行了copy,(我們通過傳入的位址和main中不同可以發現)。此時在函式中的操作都是對其拷貝的操作,不影響main函式中的origin value。缺點是,當結構體變數非常大時,編譯器對其進行複製,開銷較大。結構體位址作為引數時,子函式中操作和main函式操作的是同乙個結構體,此時傳遞的引數時乙個位址。優點是不需要進行copy,但是使用時要小心,如果不想修改其值,需用const關鍵字修飾。
資料結構套路隨筆
用線段樹可以維護區間最大值的字尾和,值得一提的技巧是可以在合併兩個快的時候向乙個塊下面遞迴,然後資訊就可以合併了。但是時間複雜度由於每次合併都要向下遞迴,所以多出乙個log。眾多樹形資料結構都可以啟發式合併,包括ac自動機也可以。具體做法是新建log快aca,每當兩塊大小相同時就合併。複雜度log。...
C語言的資料結構
資料型別 基本資料型別 構造資料型別 指標型別 空型別。1 基本資料型別 不能再分解為其他型別,如整型 int 字元型 char 浮點型 float double 列舉 enum 整型 int 十進位制 八進位制 十六進製制 a 十進位制 無字首,其數碼為0 9 b 八進位制 必須以0開頭,數碼取值...
資料結構 C語言 資料結構 查詢
二 查詢演算法的效能分析 三 基於線性表的查詢 四 基於樹的查詢 五 基於雜湊表的查詢 文章索引 分類typedef struct elemtype typedef struct sstable 從表中第一條 最後一條記錄開始,逐個進行記錄的關鍵字與給定值的比較,若某個記錄的關鍵字和給定值比較相等,...