gpt4 book ai didi

c - 用通用风格在 C 中实现堆栈

转载 作者:太空宇宙 更新时间:2023-11-04 00:52:05 24 4
gpt4 key购买 nike

文件栈.h

typedef struct
{
void *elems;
int elem_size;
int log_len;
int alloc_len;
void (*free_fn)(void *);
} stack;

void stack_new(stack *s, int elem_size, void (*free_fn)(void *));
void stack_dispose(stack *s);
void stack_push(stack *s, void *value);
void stack_pop(stack *s, void *address);

和实现文件stack.c

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#define assert(condition) if(!condition) printf("assert fail\n");exit(0)

void strfree(void *elem);

int main()
{
stack s;
int i;
char *copy, *top;
const char *friends[] = {"joe", "castiel", "lily"};
stack_new(&s, sizeof(char *), strfree);
for(i=0; i<3; i++)
{
copy = strdup(friends[i]);
stack_push(&s, &cp);
}

for(i=0; i<=3; i++)
{
stack_pop(&s, &top);
printf("%s\n", top);
}
stack_dispose(&s);
return 1;
}

void strfree(void *elem)
{
free(*(char **)elem);
}

void stack_new(stack *s, int elem_size, void (*free_fn)(void *))
{
assert(elem_size > 0);
s->alloc_len = 4;
s->free_fn = free_fn;
s->log_len = 0;
s->elem_size = elem_size;
s->elems = malloc(s->alloc_len * s->elem_size);
assert(s->elems != NULL);
}

void stack_dispose(stack *s)
{
int i;
if(s->free_fn)
{
for(i=0; i<s->log_len; i++)
{
s->free_fn((char *)s->elems + i * s->elem_size);
}
}
free(s->elems);
}

void stack_push(stack *s, void *v)
{
if(s->log_len == s->alloc_len)
{
s->alloc_len *= 2;
s->elems = realloc(s->elems, s->alloc_len*s->elem_size);
assert(s->elems != NULL);
}
memcpy((char *)s->elems+s->log_len*s->elem_size, v, s->elem_size);
s->log_len++;
}

void stack_pop(stack *s, void *address)
{
assert(s->log_len > 0);
void *source = (char *)s->elems + (s->log_len - 1) * s->elem_size;
memcpy(address, source, s->elem_size);
s->log_len--;
}

所以它编译但不运行。

  1. 它有一个来自代码的关于指针和整数比较的警告

    assert(s->elems != NULL);
  2. 某处坏了,不会打印出这里定义的三个名字

    const char *friends[] = {"joe", "castiel", "lily"};

我知道代码有点多,但我真的很想得到一些帮助,我已经束手无策了。

最佳答案

一个问题是你的 assert宏观:

#define assert(condition) if(!condition) printf("assert fail\n");exit(0) 

exit(0);无论条件为真还是假,都会执行(再次查看生成的代码)。如果需要断言,请使用标准 #include <assert.h> .

您首先发现的问题是:

assert(s->elems != NULL);

根据定义,这等同于:

if (!s->elems != NULL)
printf("assert fail\n");
exit(0);

!s->elems与空指针常量相比,是一个整数,0 或 1。因此警告。编写宏时,将参数括在括号中。至少:

#define assert(condition) if(!(condition)){printf("assert fail\n");exit(1);}

这仍然不是一个好的宏,但至少它会消除第一个编译错误,以及你的 stack_new()不会因为它被调用而在被调用时退出。请注意,出现问题时通常以非零状态退出 - 以零状态退出表示成功。

关于c - 用通用风格在 C 中实现堆栈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15048618/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com