我想要一个带字符串的堆栈。我希望能够推出和弹出字符串,以及清除整个堆栈。我认为C ++有一些方法。那怎么样?
答案 0 :(得分:8)
快速且肮脏的未经测试的示例。使用单链表结构;元素被推入并从列表的头部弹出。
#include <stdlib.h>
#include <string.h>
/**
* Type for individual stack entry
*/
struct stack_entry {
char *data;
struct stack_entry *next;
}
/**
* Type for stack instance
*/
struct stack_t
{
struct stack_entry *head;
size_t stackSize; // not strictly necessary, but
// useful for logging
}
/**
* Create a new stack instance
*/
struct stack_t *newStack(void)
{
struct stack_t *stack = malloc(sizeof *stack);
if (stack)
{
stack->head = NULL;
stack->stackSize = 0;
}
return stack;
}
/**
* Make a copy of the string to be stored (assumes
* strdup() or similar functionality is not
* available
*/
char *copyString(char *str)
{
char *tmp = malloc(strlen(str) + 1);
if (tmp)
strcpy(tmp, str);
return tmp;
}
/**
* Push a value onto the stack
*/
void push(struct stack_t *theStack, char *value)
{
struct stack_entry *entry = malloc(sizeof *entry);
if (entry)
{
entry->data = copyString(value);
entry->next = theStack->head;
theStack->head = entry;
theStack->stackSize++;
}
else
{
// handle error here
}
}
/**
* Get the value at the top of the stack
*/
char *top(struct stack_t *theStack)
{
if (theStack && theStack->head)
return theStack->head->data;
else
return NULL;
}
/**
* Pop the top element from the stack; this deletes both
* the stack entry and the string it points to
*/
void pop(struct stack_t *theStack)
{
if (theStack->head != NULL)
{
struct stack_entry *tmp = theStack->head;
theStack->head = theStack->head->next;
free(tmp->data);
free(tmp);
theStack->stackSize--;
}
}
/**
* Clear all elements from the stack
*/
void clear (struct stack_t *theStack)
{
while (theStack->head != NULL)
pop(theStack);
}
/**
* Destroy a stack instance
*/
void destroyStack(struct stack_t **theStack)
{
clear(*theStack);
free(*theStack);
*theStack = NULL;
}
修改强>
有一个如何使用它的例子会有所帮助:
int main(void)
{
struct stack_t *theStack = newStack();
char *data;
push(theStack, "foo");
push(theStack, "bar");
...
data = top(theStack);
pop(theStack);
...
clear(theStack);
destroyStack(&theStack);
...
}
您可以将堆栈声明为自动变量,而不是使用newStack()和destroyStack(),您只需要确保它们已正确初始化,如
int main(void)
{
struct stack_t myStack = {NULL, 0};
push (&myStack, "this is a test");
push (&myStack, "this is another test");
...
clear(&myStack);
}
我只是习惯于为一切创建伪构造函数/析构函数。
答案 1 :(得分:3)
尝试GNU Obstacks。
来自维基百科:
在C编程语言中,Obstack是C标准库的内存管理GNU扩展。 “障碍”是动态管理的“对象”(数据项)的“堆栈”。
维基百科的代码示例:
char *x;
void *(*funcp)();
x = (char *) obstack_alloc(obptr, size); /* Use the macro. */
x = (char *) (obstack_alloc) (obptr, size); /* Call the function. */
funcp = obstack_alloc; /* Take the address of the function. */
IMO是什么让Obstacks变得特别:它不需要malloc()
也不需要free()
,但内存仍然可以动态分配。就像alloca()
类固醇一样。它也可以在许多平台上使用,因为它是GNU C库的一部分。特别是在嵌入式系统上,使用Obstack而不是malloc()
更有意义。
答案 2 :(得分:2)