簡體   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