#ifndef STACK_H
#define STACK_H
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#define E1P5(capacity) (capacity)+=(capacity)>>1
#define STACK(Name,Data,Size,initialMax,GROWTHWAY) /
typedef struct /
{ /
Data *pData_; /
Size size_; /
}Name; /
void Name##Init(Name *p##Name) /
{ /
p##Name->pData_=(Data*)((Data**)((Size*)(malloc(sizeof(Size)+(sizeof(Data*)<<1)+sizeof(Data)*(initialMax)))+1)+2); /
if(!p##Name->pData_){errno=ENOSPC;return;} /
p##Name->size_=0; /
*((Size*)((Data**)(p##Name->pData_)-2)-1)=(initialMax); /
*((Data**)(p##Name->pData_)-2)=0;*((Data**)(p##Name->pData_)-1)=0; /
} /
void Name##Push(Name *p##Name,Data d) /
{ /
if(p##Name->size_==*((Size*)((Data**)(p##Name->pData_)-2)-1)) /
{ /
if(!*((Data**)(p##Name->pData_)-1)) /
{ /
Size capacity=*((Size*)((Data**)(p##Name->pData_)-2)-1); /
Data *pData=(Data*)((Data**)((Size*)(malloc(sizeof(Size)+(sizeof(Data*)<<1)+sizeof(Data)*(GROWTHWAY(capacity))))+1)+2); /
if(!pData){errno=ENOSPC;return;} /
*((Size*)((Data**)(pData)-2)-1)=capacity; /
*((Data**)(pData)-2)=p##Name->pData_;*((Data**)(pData)-1)=0; /
*((Data**)(p##Name->pData_)-1)=pData; /
} /
p##Name->pData_=*((Data**)(p##Name->pData_)-1);p##Name->size_=0; /
} /
p##Name->pData_[p##Name->size_++]=d; /
} /
Data Name##Pop(Name *p##Name) /
{ /
if(!p##Name->size_) /
{ /
p##Name->pData_=*((Data**)(p##Name->pData_)-2); /
if(!p##Name->pData_){Data result;memset(&result,0,sizeof(Data));errno=ENOMEM;return result;} /
p##Name->size_=*((Size*)((Data**)(p##Name->pData_)-2)-1); /
} /
return p##Name->pData_[--p##Name->size_]; /
} /
Data Name##GetTop(Name *p##Name) /
{ /
if(!p##Name->size_) /
{ /
p##Name->pData_=*((Data**)(p##Name->pData_)-2); /
if(!p##Name->pData_){Data result;memset(&result,0,sizeof(Data));errno=ENOMEM;return result;} /
p##Name->size_=*((Size*)((Data**)(p##Name->pData_)-2)-1); /
} /
return p##Name->pData_[p##Name->size_-1]; /
} /
unsigned char Name##IsEmpty(Name *p##Name) /
{return !p##Name->size_&&!*((Data**)(p##Name->pData_)-2);} /
void Name##Destroy(Name *p##Name) /
{ /
Data *pData0=*((Data**)(p##Name->pData_)-1); /
while(pData0) /
{Data *pData1=*((Data**)(pData0)-1);free((Size*)((Data**)(pData0)-2)-1);pData0=pData1;} /
do{pData0=p##Name->pData_;p##Name->pData_=*((Data**)(p##Name->pData_)-2);free((Size*)((Data**)(pData0)-2)-1);} /
while(p##Name->pData_); /
} /
void Name##SaveSpace(Name *p##Name) /
{ /
Data *pData0=*((Data**)(p##Name->pData_)-1); /
while(pData0) /
{Data *pData1=*((Data**)(pData0)-1);free((Size*)((Data**)(pData0)-2)-1);pData0=pData1;} /
*((Data**)(p##Name->pData_)-1)=0; /
}
#define EXTERNSTACK(Name,Data,Size) /
typedef struct /
{ /
Data *pData_; /
Size size_; /
}Name; /
void Name##Init(Name *p##Name); /
void Name##Push(Name *p##Name,Data d); /
Data Name##Pop(Name *p##Name); /
Data Name##GetTop(Name *p##Name); /
unsigned char Name##IsEmpty(Name *p##Name); /
void Name##Destroy(Name *p##Name); /
void Name##SaveSpace(Name *p##Name);
#endif
/*测试代码*/
#include "Stack.h"
#include <stdio.h>
STACK(S,int,unsigned,4,E1P5);
int main(void)
{
S s;
unsigned i;
unsigned j;
SInit(&s);
SPush(&s,1);
printf("%4d",*((unsigned*)((int**)(s.pData_)-2)-1));
for(i=0;i!=s.size_;++i)
printf("%4d",s.pData_[i]);
printf("/n");
printf("%4d",SGetTop(&s));
printf("%4d/n", SPop(&s));
for(i=0;i!=20;++i)
{
SPush(&s,i);
printf("%4d",SGetTop(&s));
printf("%4d",*((unsigned*)((int**)(s.pData_)-2)-1));
for(j=0;j!=s.size_;++j)
printf("%4d",s.pData_[j]);
printf("/n");
}
printf("/n");
while(!SIsEmpty(&s))
{
printf("%4d",SGetTop(&s));
if(!s.size_)printf("/nError!/n");
printf("%4d",*((unsigned*)((int**)(s.pData_)-2)-1));
for(j=0;j!=s.size_;++j)
printf("%4d",s.pData_[j]);
printf("/n");
SPop(&s);
}
SSaveSpace(&s);
printf("errno : %x/n",errno);
printf("??/n");
SDestroy(&s);
return 0;
}