首先,我們需要在棧中設定乙個抽象的儲存結構, void *elem, 其需要動態分配堆記憶體, 宣告如下所示:
typedef struct stack;void (*freefn)(void *elem) 為函式指標,其表示用於**抽象指標(void *elem)中,需要**的資料,比如動態分配的字串和結構體中動態分配的內容,我們可以通過傳遞函式指標,使得在**棧時,不必彈出所有棧中資料進行**,而是通過stackdestroy呼叫我們定義的**方法,進行資料**。void stacknew(stack *s, int elem_size, void (*freefn)(void *elem));
void push(stack *s, void *elem);
void pop(stack *s, void *result);
void stackdestroy(stack *s);
具體實現如下所示:
#include #include #include void stacknew(stack *s, int elem_size, void (*freefn)(void *elem))由於我們不知道資料型別是什麼,所以在初始化棧時,我們需要傳遞資料型別的大小,在進行資料彈出和壓入的時候,我們可以對記憶體直接進行拷貝工作,這樣做的優點是顯而易見的。不要忘記,elem_size*length才是需要分配堆記憶體的大小。static void stackgrow(stack *s)
void push(stack *s, void *elem)
void *address;
address = (char *)s->elem + s->position * s->elem_size;
memcpy(address, elem, s->elem_size);
s->position++;
}void pop(stack *s, void *result)
void stackdestroy(stack *s)
free(s->elem);
}
呼叫時,如下所示:
#include #include #include #include "stack4.h"
using namespace std;
static char * strdup(const char * source)
void freefn(void *element)
int main() ;
stack *s = (stack *) malloc(sizeof(stack));
stacknew(s, sizeof(char *), freefn);
int i=0;
for(;i < 4; i++)
char *result;
pop(s, &result);
cout << result << endl;
//**pop的資料
free(result);
//有了固定的**函式後,不必彈出所有的棧中資料,即可**記憶體
//若沒有,**記憶體時,必須彈出所有棧中資料,手動進行**,然後**棧記憶體
stackdestroy(s);
free(s);
getchar();
return 0;
}
使用深度拷貝字串,是考慮到了實際應用中,動態分配內容的生命週期。
還需注意的是,在壓棧時,必須對指向動態分配字串的指標位址進行操作,因為我們在棧的初始化時,傳遞的資料大小是sizeof(char *),另一方面,也有助於棧的高效操作。
棧操作之棧鏈
資料結構 棧是允許在同一端進行插入和刪除操作的特殊線性表。允許進行插入和刪除操作的一端稱為棧頂 top 另一端為棧底 bottom 棧底固定,而棧頂浮動 棧中元素個數為零時稱為空棧。插入一般稱為進棧 push 刪除則稱為退棧 pop 棧也稱為後進先出表。作業系統 由編譯器自動分配釋放 存放函式的引數...
程式設計正規化 程式設計的本質
程式設計正規化的種類 很多人認同的兩個觀點 程式 資料結構 演算法 這個表示式認為,如果資料結構設計得好,演算法也會變得簡單,而且乙個好的通用的演算法應該可以用在不同的資料結構上。演算法 控制 業務邏輯 這個表示式則想表達的是資料結構不複雜,複雜的是演算法,演算法由兩個邏輯組成,乙個是真正的業務邏輯...
《架構整潔之道》之程式設計正規化總覽
結構化程式設計是第乙個普遍被採用的程式設計正規化 但是不是第乙個被提出的 由edsger wybe dijkstra於1968年最先提出。與此同時,dijkstra還論證了使用goto這樣的無限制跳轉語句將會損害程式的整體結構。結構化程式設計正規化歸納 結構化程式設計對程式控制權的直接轉移進行了限制...