C++编程范式栈的泛型写法

贴代码:


stack.h

 struct   stack
{
	void * elems;  //指向栈中首元素
	int logicallen;  //当前栈空间中的元素个数
	int allocalength;//栈空间的实际大小
	int elemSize;//栈中元素占用字节数
	void  (*freefn)(void *); //函数指针,清除函数指针




};

stack.cpp

#include "stack.h"
#include <iostream.h>
#include<stdlib.h>
#include "assert.h"
#include "memory.h"
#include "string.h"
#include <stdio.h>
void objdelete(void * elem){


    if(elem == NULL){
        return;
    }


    //char  ** elem 获得elem指针的地址,然后* X表示获得上面地址存放的指针
    //char ** 相当强制转换elem为指针的指针,指向的是一个指针,前面加*号就是获得elem指针。
    //转化为二级指针,距离真正的字符有两跳之遥,然后解引用
    free(*(char**)elem);
}
/************************************************************************/
/*  创建一个栈空间                                                                      */
/************************************************************************/
void stackNew(stack *s,int elemSize,void (*freefn)(void *)){


    s->logicallen=0;
    s->allocalength=4;
    s->elemSize=elemSize;
    s->elems=malloc(4*elemSize); //申请栈空间
    s->freefn = freefn;
};
/************************************************************************/
/* 释放栈空间                                                                      */
/************************************************************************/
void stackDispose(stack *s){
    if(s->freefn != NULL){
        for(int i=0;i<s->logicallen;i++){
            void * target = (char*)s->elems+i*s->elemSize;
            s->freefn(target);
        }    
    }
    free(s->elems);




};
void StackPop(stack *s,void *elemAddr)  
{  
    void *sourse=(char *)s->elems+(s->logicallen-1)*s->elemSize;  
    memcpy(elemAddr,sourse,s->elemSize);  
    s->logicallen--;  
}  


/************************************************************************/
/*        chuzhan                                                              */
/************************************************************************/


/************************************************************************/
/* 将元素elem入栈                                                                    */
/************************************************************************/
// 
// void stackPush(stack *s,void *add){
// 
//     if(s->logicallen == s->allocalength){
//         s->allocalength *=2; //等价于s->allocalength = s->allocalength*2
//         s->elems = (int *)realloc(s->elems,s->allocalength*sizeof(int));
//     }
//     assert(s->elems != NULL);
//     s->elems[s->logicallen] =value;
//     s->logicallen++;
// };


void stackGrow(stack *s){


    s->allocalength*=2;
    s->elems = realloc(s->elems,s->elemSize*s->allocalength);


}




/************************************************************************/
/* 将元素elem入栈                                                                    */
/************************************************************************/
void stackPush(stack *s,void *elemAddr){


    if(s->logicallen == s->allocalength){
        stackGrow(s); //需要扩容了


    }
    //手动计算元素地址,因为void*类型,系统比不知道该怎么处理。所以需要自己计算出入栈和出栈时元素的地址。
    //从add地址下的内容拷贝到target的地址,拷贝长度为elemSize
    cout<<"elems"<<s->elems<<endl;
    cout<<"logicallen"<<s->logicallen<<endl;
    cout<<"elemSize"<<s->elemSize<<endl;
    void * target = (char *)s->elems+s->logicallen*s->elemSize;


    memcpy(target,elemAddr,s->elemSize);




    s->logicallen++;


};




void main(){

const char *friends[3] = {"Al","Bob","Carl"};
    stack *s=new stack();
    stackNew(s,sizeof(char *),objdelete);
    int leng = sizeof(friends)/4;
    cout<<leng<<endl;
    for(int i=0;i<leng;i++){
        char * copy=strdup(friends[i]);//strdup内部调用了malloc,需释放内存;返回指向被复制的字符串的指针
        stackPush(s,&copy);
    }
    char *name;  
  //  for(int idx=0;idx<3;idx++)  
  //  {  
  //      StackPop(s,&name);     


  //  }  
    stackDispose(s);


}

总结:

下面这个方法就是获得top的地址。入栈。

void * target = (char *)s->elems+s->logicallen*s->elemSize;


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值