[英]Conflicting types for function in C
我编写了一个pop函数,该函数会弹出字符运算符(+,*,-,/)的链接列表堆栈,并返回弹出的值。 问题是我收到“冲突类型错误”。 而且我似乎无法找出问题所在。 我的linkedCharStack结构声明为:
typedef struct linkedcharStack
{
char elem;
struct linkedcharStack* next;
};
堆栈的头在pop(不是全局的,而是指针)之外的另一个函数中声明为:
struct linkedcharStack * opstack = malloc(sizeof(struct linkedStack));
我的实际弹出功能是:
char poptheop(struct linkedcharStack* s1){
struct linkedcharStack* temp;
if(s1==NULL){
printf("NULL TOP ON POP VALUE STACK!");
}
char returnvalue = s1->elem;
temp = s1;
s1 = s1->next;
free(temp);
return returnvalue;
}
除了编译错误,我还可以在您的代码中看到一个问题:您没有正确实现poptheop,因为您对s1指针所做的更改不会报告给调用者。 您应该做的就是将一个指针传递给该指针:
char poptheop(struct linkedcharStack** s1){
struct linkedcharStack* temp;
if(s1==NULL){
printf("NULL TOP ON POP VALUE STACK!");
}
char returnvalue = (*s1)->elem;
temp = *s1;
*s1 = temp->next;
free(temp);
return returnvalue;
}
您需要这样做,否则您的堆栈顶部在弹出后将不会被修改。
如果我们分成两个结构,它会更通用,并且可能更易于理解/使用:一个用于堆栈控制,另一个用于该堆栈中的元素:
// stack element
struct _stackelem;
typedef struct _stackelem elem_t;
struct _stackelem {
elem_t *prev;
elem_t *next;
char elem;
int precedence;
};
// stack control
struct _stack;
typedef struct _stack stack_t;
struct _stack {
elem_t *head;
elem_t *tail;
long maxcnt;
long curcnt;
};
stack_t opStack;
other_func()
{
opStack.tail = malloc(sizeof(elem_t));
}
请注意,我在堆栈控件中添加了“ head”,在elem_t中添加了“ prev”。 这允许stack_t成为双链表,并且可以根据需要在堆栈之外实现队列。 另外,我在elem_t中添加了“优先级”,详情请参见下文。
这是您的原始功能[与ASH相似的更正]:
// RETURNS: -1=empty stack
char
poptheop_original(stack_t *stk)
{
elem_t *tmp;
char retval;
tmp = stk->tail;
// stack is empty
if (tmp == NULL)
retval = -1;
// pop last element
else {
retval = tmp->elem;
stk->tail = tmp->next;
free(tmp);
}
return retval;
}
现在,“(* s1)”已替换为“ stk-> tail”。 我们避免传递“ **”,并且代码将以同样快的速度执行。
但是,如果您只需要“ elem”,我会考虑将操作堆栈重新实现为可重新分配的数组(例如,“ char * opstack”)。
使用链表方法更适合返回更复杂的东西。 这就是为什么我添加“优先级”。 这是您原始功能的调整,因此您可以同时获得“ elem”和“ precedence”:
// RETURNS: elem is -1 on empty stack
elem_t
poptheop_struct(stack_t *stk)
{
elem_t *tmp;
elem_t retval;
tmp = stk->tail;
// stack is empty
if (tmp == NULL) {
retval.elem = -1;
retval.precedence = -1;
}
// pop last element
else {
retval = *tmp;
stk->tail = tmp->next;
free(tmp);
}
return retval;
}
请注意,此功能仍在内部执行“免费”操作。 但是,它通过值传递了结构。 几乎从来没有一件好事。
这是最终版本,它返回指向弹出的elem_t的指针:
// RETURNS: NULL is empty
elem_t *
poptheop_pointer(stack_t *stk)
{
elem_t *retval;
retval = stk->tail;
// pop stack
if (retval != NULL)
stk->tail = retval->next;
return retval;
}
现在,您必须自己释放指针,这是不利的一面。 但是好处是elem_t可以具有许多数据元素,而不仅仅是elem和priority,并且可以快速执行而无需复制多余的数据。
拆分stack_t的另一个好处是,您可以隐藏如何实现堆栈的详细信息。 它可能是一个单链表(如您所完成的),一个双链表或我之前提到的realloc数组。
如果您愿意,可以通过练习将stack_t重新实现为可重新分配的数组。 这就是为什么我添加了“ maxcnt”和“ curcnt”。 如果发现数组方法更合适,则可以从elem_t中完全消除“ prev”和“ next”。
进一步提示:仅在curcnt即将溢出maxcnt时,才需要在推送期间重新分配。 将realloc做为maxcnt + slop_factor来防止进行过多的realloc。 这将使其变得“智能”。
这可能是最适合您的实现-YMMV
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.