2012-04-25 141 views
0

我們與在C. LinkedList的一個問題,當我應該算多少節點出現在列表中,我總是得到1LinkedList的添加元素

LL數:1

這是添加,計數和獲得的代碼列表最後一個元素:

void addLL(LL * head) 
{ 
LL *newNode; 
LL *tail = getLastNode(head); 

newNode = malloc(sizeof(LL)); 
if(newNode != DEF_NULL) 
{ 
    newNode->ID=-1; 
    newNode->TCB=-1; 
    newNode->next = DEF_NULL; 

    if(!head) head = newNode; 
    else tail->next = newNode;  
} 
} 

LL * getLastNode(LL * head) 
{ 
    LL *temp = head; 
    while(temp->next != DEF_NULL) 
    { 
     temp = temp->next; 
    } 
    return temp; 
} 

CPU_INT32U countLL(LL * head) 
{ 
    CPU_INT32U elements = 0; 
    LL * temp = head; 
    while(temp->next != DEF_NULL) 
    { 
     temp = temp->next; 
     elements++; 
    } 
    return elements; 
} 

這就是所謂的以這樣的方式

addLL(list); 
temp = countLL(list);  
Debug_LOG("LL count: %i", temp); 

其中LL * list;是一個全局變量,temp在本地範圍內。 我希望每個人都可以看到我錯在哪裏

問候, Sjaak和格里特

+0

你確定該列表不爲空值,則與newNode = malloc的添加僅一個元素(的sizeof(LL)); – subbul 2012-04-25 10:27:49

+0

這裏有什麼問題?如果你添加一個元素,計數將只是一個元素...添加更多的元素來測試你的'countLL()' – 2012-04-25 10:30:15

+0

對不起,我應該說每一秒都會在主程序中調用AddLL。 – Davey 2012-04-25 10:31:32

回答

0

我看到你的代碼的幾個問題:

  • 你應該總是通過測試保護您的鏈接列表操作如果列表指針有效(即不空)
  • 由於分配第一個新項目的方式,您不能將第一個項目分配給空列表:您更改了head,但修改不會傳播到函數之外。 你應該傳遞一個「指針指向列表指針」(即LL**),相當於「LL*的地址」;看我怎麼稱呼addLL()我是如何修改它的原型和head分配
  • 如果你的列表只有一個街區之長,它不會因爲你只計算,如果有一個繼任,看我怎麼有計體改該做的訂單/ while條件

我建議修改的代碼爲1,2或任何列表的長度(我剛剛換了CPU_INT32Uint工作與MinGW的快速編譯,我可以的typedef」內):

#include <stdio.h> 

#define DEF_NULL 0 

typedef struct tagL { 
    int ID; 
    int TCB; 
    struct tagL *next; 
} LL; 

void addLL(LL ** head); 
LL * getLastNode(LL * head); 
int countLL(LL * head); 

void addLL(LL ** head) 
{ 
    LL *newNode; 
    LL *tail = getLastNode(*head); 

    newNode = malloc(sizeof(LL)); 
    if(newNode != DEF_NULL) 
    { 
     newNode->ID=-1; 
     newNode->TCB=-1; 
     newNode->next = DEF_NULL; 

     if(!*head) 
      *head = newNode; 
     else 
      tail->next = newNode;  
    } 
} 

LL * getLastNode(LL * head) 
{ 
    LL *temp = head; 
    if (head){ 
     while(temp->next != DEF_NULL) 
     { 
      temp = temp->next; 
     } 
    } 
    return temp; 
} 

int countLL(LL * head) 
{ 
    int elements = 0; 
    LL * temp = head; 
    if (head){ 
     do { 
      temp = temp->next; 
      elements++; 
     } while(temp != DEF_NULL); 
    } 
    return elements; 
} 

int main(int argc, char *argv[]){ 
    LL *list = 0; 

    printf("LL test\n"); 
    addLL(&list); 
    printf("length = %d\n", countLL(list)); 
    addLL(&list); 
    printf("length = %d\n", countLL(list)); 
    addLL(&list); 
    printf("length = %d\n", countLL(list)); 
} 

輸出:

LL test 
length = 1 
length = 2 
length = 3 
+0

非常感謝Seki,它現在運行良好..我明白了指針指向的想法,所以你有指針的地址..這將在任何地方進行編輯。我的第一個想法是,它已經是一個指針,所以如果我在那裏改變它,它會在任何地方改變。現在好了,非常感謝! – Davey 2012-04-25 11:29:40

+0

@Davey:歡迎您:o)如果我的回答很有幫助,請點擊左邊的白色複選標記,選擇它作爲「答案」。 – Seki 2012-04-25 11:38:21

+0

所以我做了= D – Davey 2012-04-25 11:53:56

0

在Windows上沒有什麼是錯的白衣這個功能 - 奇怪......

ideone also shows good output.

#include <stdio.h> 
#include <stdlib.h> 

typedef struct LL{ 
    struct LL *next; 
}LL; 

LL * getLastNode(LL * head) 
{ 
    LL *temp = head; 
    while(temp->next != NULL) 
    { 
     temp = temp->next; 
    } 
    return temp; 
} 

void addLL(LL * head) 
{ 
LL *newNode; 
LL *tail = getLastNode(head); 

newNode = malloc(sizeof(LL)); 
if(newNode != NULL) 
{ 
    newNode->next = NULL; 

    if(!head) head = newNode; 
    else tail->next = newNode;  
} 
} 

int countLL(LL * head) 
{ 
    int elements = 0; 
    LL * temp = head; 
    while(temp->next != NULL) 
    { 
     temp = temp->next; 
     elements++; 
    } 
    return elements; 
} 

int main() { 
    LL *h = malloc(sizeof(*h)); 
    addLL(h); 
    addLL(h); 
    addLL(h); 
    printf("%d\n", countLL(h)); // prints 3 as expected 
} 
+0

'addLL()'是錯誤的,因爲它不能添加到一個空列表中,所以你在'main()'中手動分配一個LL來欺騙... – Seki 2012-04-25 11:07:06

0

CPU_INT32U countLL (LL * head){CPU_INT32U elements = 0; LL * temp = head; while(temp-> next!= DEF_NULL){temp = temp-> next; elements ++;} return elements;}

這個功能您聲明元素作爲汽車 所以它的存儲,即會釋放的函數退出變量,內存現在可以自由地分配給不同的變量

,因此可能會被覆蓋,因此以前cvalue丟失

所以避免這種情況,請使用靜態的聲明變量..... 爲靜態變量的內存只獲得整個項目的 請嘗試執行後釋放....

0
void addLL(LL * head) 
{ 
LL *newNode; 
LL *tail = getLastNode(head); 

有一個問題就在這裏,如果(全球)head恰好是NULL,它將被getLastNode()函數解引用上:

LL * getLastNode(LL * head) 
{ 
    LL *temp = head; 
    while(temp->next != DEF_NULL) 

這裏temp->next != ...將導致臨時解除引用。如果temp恰好爲NULL,那會導致NULL指針解引用。 (如通過插入函數調用,您可以添加額外的測試(或使用指針的指針是清潔劑):

while(temp && temp->next != DEF_NULL) 

更新(以表明指針的指針版本是清潔)

#include <stdlib.h> 
#include <stdio.h> 
#define DEF_NULL NULL 
#define CPU_INT32U unsigned 

typedef struct link { 
     struct link *next; 
     } LL; 

LL *globhead=NULL; 
LL **getTailPP(LL **ppHead); 
CPU_INT32U countLL(LL * ptr); 
void addLL(LL **ppHead); 

void addLL(LL **ppHead) 
{ 
ppHead = getTailPP(ppHead); 

*ppHead = malloc(sizeof **ppHead); 
    if(*ppHead != DEF_NULL) 
    { 
     // newNode->ID=-1; 
     // newNode->TCB=-1; 
     (*ppHead)->next = DEF_NULL; 
    } 
} 

LL **getTailPP(LL **ppHead) 
{ 
    for(; *ppHead; ppHead = &(*ppHead)->next) {;} 
    return ppHead; 
} 

CPU_INT32U countLL(LL * ptr) 
{ 
    CPU_INT32U elements = 0; 
    for(; ptr != DEF_NULL; ptr=ptr->next) { elements++; } 
    return elements; 
} 

int main() 
{ 
unsigned count; 

addLL(&globhead); 
count = countLL (globhead); 
printf("count = %u\n", count); 

addLL(&globhead); 
count = countLL (globhead); 
printf("count = %u\n", count); 

return 0; 
} 
+0

謝謝wildplasser ..你解釋了指針指針的事實。在我看來,它就像是:'我已經在使用一個指針了,所以生病了',但是當然,指針也需要一個指針。非常感謝!也用於測試整個事情..真棒有多少人想要幫助! – Davey 2012-04-25 11:31:15

+0

如果你仔細想想,唯一發生的事情就是* * NULL的指針將被賦予新元素的值。不管那個指針是頭指針還是某個 - >下一個指針都不重要。這是一個指向LL的指針,這是重要的。只有一個賦值:曾經是NULL的指針獲取一個值。 – wildplasser 2012-04-25 11:34:49

相關問題