体验C语言内存操作的魅力之范型

     用C语言来实现堆栈的范型,体验C语言的真正魅力。相比C++里的范型,用C语言实现感觉更真切,更踏实,同时体会到了对内存把控的快乐,我想再这样下去我会上瘾。这里面唯一要说的两处:分别是realloc和程序第28行。


     realloc在分配内存时,如果指针先前分配的内存范围后有足够的未分配的内存,则在末尾直接加上需要扩展的内存,反之分配一块新的内存,将之前的字符拷贝进去。对应图二和图一。

     第28行比较难理解的是,要改变指针指向地址的内容,需要将值复制到指向的内存地址。对应图三。

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#define BASE_LENGTH 4
typedef struct{
    void* elements;
    int elementSize;
    int allocSize;
    int pos;
}Stack;

void StackNew(Stack* s, int size) {
    s->elementSize = size;
    s->pos = 0;
    s->allocSize = size * BASE_LENGTH;
    s->elements = malloc(s->allocSize);
    assert(s->elements != NULL);
}

void StackPush(Stack* s, void* element) {
    if(s->pos == s->allocSize) {
        s->allocSize *= 2;
        s->elements = realloc(s->elements, s->allocSize);
        assert(s->elements);
    }
    void* next = (char*)s->elements + s->pos;
    memcpy(next, element, s->elementSize);
    s->pos += s->elementSize;
}

void StackPop(Stack* s) {
    if(s->pos == 0) {
        printf("Error: Stack is null\n");
        return;
    }
    s->pos -= s->elementSize;
}

void StackFree(Stack* s) {
    free(s->elements);
}
int main() {
    Stack s;
    int i = 0;
    double d = 0.233;
    StackNew(&s, sizeof(double));
    /*-------Test stack push-----*/
    for(i = 0; i < 10; ++i) {
        d = d * 2;
        StackPush(&s, &d);
    }

    double *arr = s.elements;
    printf("\nafter push the num is:");
    for(i = 0; i < s.pos/sizeof(double); ++i) {
        printf("%f\n", arr[i]);
    }

    /*-------Test stack pop------*/
    StackPop(&s);
    printf("\nafter pop the num is:");
    for(i = 0; i < s.pos/sizeof(double); ++i) {
       printf("%f\n", arr[i]);
    }

    StackFree(&s);
    return 0;
}

程序编译环境是gcc version 4.2.1。全文完。


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值