C-一個棧的實現

網易公開課學習,一個棧的實現,VC2010控制檯程序編譯通過:

// testVC.cpp : 一個棧的實現。
//
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <assert.h>
typedef struct {
 int loglength;  //棧中元素數量
 int alloclength; //分配棧長度
 int elemsize;  //元素長度
 void * elems;  //棧空間
 void (* freefn)(void *); //釋放內存函數
} Stack;
void StackNew(Stack * s,int elemsize, void (* freefn)(void *));
void StackDispose(Stack * s);
void StackPush(Stack *s,void * elemaddr);
void StackPop(Stack *s,void * elemaddr);
void StackGrow(Stack *s);
void stringfree(void * elem);
int _tmain(int argc, _TCHAR* argv[])
{
 const char *friends[] = {"Alan","Bob","Carl","Frank","Mike"};
 Stack stringStack;
 
 //對字符串而言,壓入棧的是字符串地址,因此元素長度爲sizeof(char*)
 StackNew(&stringStack,sizeof(char*),stringfree);
 for(int i=0;i<5;i++)
 {
  char * copy = strdup(friends[i]); //在heap上分配內存
  StackPush(&stringStack,&copy); 
 }
 char *name;
 for(int i=0;i<5;i++)
 {
  StackPop(&stringStack,&name);
  printf("%s\n",name);
  free(name);  //因爲這塊內存是strdup分配的,使用完畢後必須free
 }
 StackDispose(&stringStack);
 const int intarr[] = {1,2,3,4,5,6};
 Stack intStack;
 //對int而言,壓入棧的是int值本身,因此元素長度爲sizeof(int),且無需freefn
 StackNew(&intStack,sizeof(int),NULL);
 for(int i=0;i<6;i++)
 {
  StackPush(&intStack,(void *)&intarr[i]); 
 }
 int val;
 for(int i=0;i<6;i++)
 {
  StackPop(&intStack,&val);
  printf("%d\n",val);
 }
 StackDispose(&intStack);
 return 0;
}
/*
**初始化棧
*/
void StackNew(Stack * s,int elemsize, void (* freefn)(void *))
{
 s->alloclength = 4;
 s->loglength = 0;
 s->elemsize = elemsize;
 s->freefn = freefn;
 s->elems = malloc(4*elemsize);
 assert(s->elems != NULL);
}
/*
**釋放棧
*/
void StackDispose(Stack * s)
{
 if(s->freefn != NULL) {
  for(int i=0;i<s->loglength;i++)
  {
   void * elem = (char *)s->elems + i * s->elemsize;
   s->freefn(elem);
  }
 }
 free(s->elems);
}
/*
**擴展棧
*/
void StackGrow(Stack *s)
{
 s->alloclength *= 2;
 s->elems = realloc(s->elems,s->alloclength*s->elemsize);
 assert(s->elems != NULL);
}
/*
**將元素壓入棧
*/
void StackPush(Stack *s,void * elemaddr)
{
 if(s->loglength == s->alloclength)
 {
  StackGrow(s);
 }
 void * target = (char *)s->elems + s->loglength * s->elemsize;
 memcpy(target,elemaddr,s->elemsize);
 s->loglength ++;
}
/*
**彈出棧頂元素
**/
void StackPop(Stack *s,void * elemaddr)
{
 s->loglength --;
 void * source  = (char *)s->elems + s->loglength*s->elemsize;
 memcpy(elemaddr,source,s->elemsize);
}
/*
**自定義字符串free函數
*/
void stringfree(void * elem)
{
 free(*(char **)elem);
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章