问题描述
我有以下struct元素:
typedef struct struct_element{
Tache t;
struct struct_element *suivant;
}Element;
typedef Element* Liste;
我正在尝试创建一个函数“ ajoutdeb”,该函数应该创建一个新元素,并将列表中当前的第一个元素作为新元素的下一个元素。这样,新元素将被放置在链表的开头。这是我的实现:
void ajoutdeb(Liste* l,Tache t)
{
Element e;
e.t = t;
e.suivant = *l;
*l = &e;
}
我的问题是,新元素的下一个元素是本身。我的函数逻辑出了什么问题?
示例代码:
#include <stdio.h>
typedef struct{
int no; /*le nom de la tache*/
int duree; /* la duree de la tache*/
int nbPred; /* le nombre effectif de predecesseur de la tache*/
int pred[16]; /*le tableau des predecesseurs*/
char titre[256]; /*le titre de la tache*/
}Tache;
typedef struct struct_element{
Tache t;
struct struct_element *suivant;
}Element;
typedef Element* Liste;
void ajoutdeb(Liste* l,Tache t)
{
Element e;
e.t = t;
e.suivant = *l;
*l = &e;
}
int main()
{
int nb;
Liste liste = NULL;
Tache t1 = {
.titre = "Init",.no = 0
};
Tache t2 = {
.titre = "Deuxième",.no = 1
};
ajoutdeb(&liste,t1);
ajoutdeb(&liste,t2);
return 0;
}
解决方法
在您的ajoutdeb()
函数中,您需要返回类型才能指示将新节点添加到调用函数的成功或失败。使返回类型成为指向节点的指针是一个不错的选择。失败时,您可以返回NULL
;成功时,您可以返回列表的新头节点。
您的ajoutdeb()
函数需要:
- 分配和验证新节点的存储空间;
- 完全初始化该节点的值和指针;和
- 将新节点插入列表的新标题(称为前向链接节点)
由于分配了新节点,因此必须 验证 ,分配成功后才能继续进行功能。如果分配失败,则返回NULL
以指示失败。如果成功,则可以将节点添加到列表中。
完全将其放入,您可以执行以下操作:
Element *ajoutdeb(Element **l,Tache t)
{
Element *e = malloc (sizeof *e);
if (!e) { /* validate EVERY allocation */
perror ("malloc-e");
return NULL; /* return NULL on failure */
}
e->t = t; /* fully initialize new node */
e->suivant = NULL;
e->suivant = *l; /* make e->suivant point to list */
*l = e; /* update list pointer to current */
return *l; /* return new head node on success */
}
(注意:避免键入错误的指针。这会隐藏一定程度的间接性。在60行代码中,可能很容易查看屏幕顶部以回想起Liste
实际上是Element*
类型,但是在处理许多类型的指针和间接级别时,这变得越来越困难了6000行。请参阅Is it a good idea to typedef pointers?)
您可能希望检查Singly Linked List (node only,no wrapper)的其他实现细节,然后查看Singly Linked List of Integers (example)的好处是使用tail
指针在末尾提供O(1)插入您的需求发生变化时,列表中的第一个。
如果您还有其他问题,请告诉我。