我被指派用ANSI C编写一个通用堆栈。它是为原始数据类型编写的。在此之前,没有什么大问题。
后来我被要求重新编程我的应用程序,以便即使是复杂的数据类型也可以在我的堆栈上使用。
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stddef.h>
#include "genstacklib.h"
void (*freefn) (void*);
/*
* ToDo
*/
void GenStackNew(genStack *s, int elemSize, void (*freefunk) (void*))
{
s->elems = malloc (elemSize * GenStackInitialAllocationSize);
freefn = freefunk;
assert (s->elems != NULL);
s->elemSize = elemSize;
s->logLength = 0;
s->allocLength = GenStackInitialAllocationSize;
}
/*
* ULStackPush adds an element to the stack and allocates new memory if
* needed. If there is not enough memory, ULStackPush does nothing.
*/
void GenStackPush (genStack *s, const void *elemAddr)
{
/*assert (sizeof(*elemAddr) == s->elemSize);*/
assert (s->elems != NULL);
if (s->logLength == s->allocLength)
{
void *temp = NULL;
temp = realloc (s->elems, 2 * s->allocLength * s->elemSize);
assert (temp != NULL);
s->allocLength = 2 * s->allocLength;
s->elems = temp;
}
memcpy(currentval(s), elemAddr, s->elemSize);
s->logLength = s->logLength + 1;
}
void GenStackPop (genStack *s, const void *elemAddr)
{
assert (s->elems != NULL);
assert (s->logLength != 0);
(s->logLength)--;
memcpy((void *)elemAddr, currentval(s), s->elemSize);
}
void *currentval(genStack *s)
{
assert (s->elems != NULL);
return ((size_t*)s->elems + s->logLength * s->elemSize);
}
bool GenStackEmpty (const genStack *s)
{
assert (s->elems != NULL);
return s->logLength == 0;
}
void GenStackDispose (genStack *s)
{
assert (s->elems != NULL);
s->logLength = 0;
free (s->elems);
freefn();
}
/*
* ToDO
*/
void *freefn (void *) {
free
我的header数据是:
#ifndef GENSTACKLIB_H
#define GENSTACKLIB_H
#include <stdbool.h>
#define GenStackInitialAllocationSize 4
typedef struct
{
void *elems;
int elemSize;
int logLength;
int allocLength;
} genStack;
void GenStackNew (genStack * s, int elemSize);
bool GenStackEmpty (const genStack * s);
void GenStackPush (genStack * s, const void *elemAddr);
void GenStackPop (genStack * s, const void *elemAddr);
void GenStackDispose (genStack * s);
void *currentval(genStack *s);
#endif
在第一个代码块中,我相信必须要做的事情是在ToDo标记中。我如何才能将堆栈用于复杂的数据类型?
先谢了
2条答案
按热度按时间zkure5ic1#
我不认为像字符串这样的“复杂”类型有任何问题......字符串指针和整型指针之间没有真实的的区别。所以只要存储指针(或指针指针)就可以了。
因此,元素不是“int”..元素是指向指针的指针。
以非常“伪”C代码的形式表达的基本思想
hsvhsicv2#
使用堆栈,我们不知道可能需要多少项。
使用byte* 或(char*)来存储内存的内容,而不是void*(void * 也可以工作,但是我们可能需要填充分配,以包含结构体)
将内存复制到一个新的分配中,该分配被推送到堆栈上,然后在弹出时删除已使用的内存。
创建用于跟踪堆栈的结构
初始化堆栈,包括我们将要使用的类型的大小
总是,我们需要手动释放堆栈,以防不是所有的都弹出
将一项压入堆栈
有时我们不想使用局部变量,即:stack_pop_(stack,&type)我们可以使用stack_push_arg_no_ref(stack,10)。
现在我们可以弹出,并使用相同的peek,传递(NULL)到数据将导致一个peek,返回(1),如果有一个项目在堆栈中,和一个(0),如果它的空
}
最后我们可以实现堆栈
使用任何ANSI C数据类型
使用字符串
确保释放堆栈
使用整数