2012-04-25 140 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

相关问题