我们在 C 语言中的 LinkedList 有问题。当我计算列表中应该有多少个节点时,我总是得到 1
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 在局部范围内。我希望任何人都可以看到我哪里出错了
问候斯雅克和格里特
我在您的代码中看到几个问题:
- 您应该始终通过测试列表指针是否有效(即不为 null)来保护链表操作
- 由于分配第一个新项目的方式,您无法将第一个项目分配给空列表:您更改了
head
但修改不会传播到函数之外。您应该传递一个等效于"LL*
地址"的"指向列表指针的指针"(即LL**
);看看我如何调用addLL()
以及如何修改其原型和head
分配 - 如果你的列表只有一个区块长,它不会被计算在内,因为只有当有继任者时你才会被计算在内,看看我是如何修改 do/while 条件的顺序的
提出了适用于 1、2 或任何列表长度的修改代码(我刚刚将CPU_INT32U
更改为 int
以便使用 MinGW 快速编译,我可以 typedef'ined):
#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 testn");
addLL(&list);
printf("length = %dn", countLL(list));
addLL(&list);
printf("length = %dn", countLL(list));
addLL(&list);
printf("length = %dn", countLL(list));
}
输出:
LL test
length = 1
length = 2
length = 3
在 Windows 上,这个功能没有任何问题 - 奇怪......
IDEe也显示出良好的输出。
#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("%dn", countLL(h)); // prints 3 as expected
}
CPU_INT32U countLL(LL * head){CPU_INT32U elements = 0;LL * temp = head;while(temp->next != DEF_NULL){temp = temp->next;elements++;}返回元素;}
在此函数中,您将元素变量声明为 auto所以一旦函数退出,它的存储就会被释放,因为内存现在可以自由分配给不同的变量,所以可能会被覆盖,因此以前的 cvalue 会丢失
所以为了避免这种情况,请在声明变量时使用静态.....由于静态变量内存仅在执行整个程序后才会释放请尝试....
void addLL(LL * head)
{
LL *newNode;
LL *tail = getLastNode(head);
这里有一个问题,如果(全局)头恰好是 NULL,它将被 getLastNode() 函数取消引用:
LL * getLastNode(LL * head)
{
LL *temp = head;
while(temp->next != DEF_NULL)
在这里temp->next != ...
将导致 temp 被取消引用。如果 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 = %un", count);
addLL( &globhead);
count = countLL (globhead);
printf("count = %un", count);
return 0;
}