繁体   English   中英

C中函数的冲突类型

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM