用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。全文完。