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