我想做一个简单的链表编程。这是我的代码我期望输出有4行
Tugi 1
比尔2 3甜4
三春
,但输出仅为Tugi 1。我的代码有什么问题?
我被要求做另一个关于链表的作业,但是我的教授没有解释好,所以我只是想做一个简单的程序来测试链表。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct _member{
char name[20];
int number;
struct _member* next; //pointer to the next structure
}
MEMBER;
void AddMember(MEMBER* start, char* namae, int num);
MEMBER* NewMember(char* namae, int num);
//void FreeLink(MEMBER* start);
void PrintMember(MEMBER* start);
int main(){
static int serialNum=1;
MEMBER* start = NewMember("Tugi", serialNum++);
AddMember(start, "Bill", serialNum++);
AddMember(start, "Sweet", serialNum++);
AddMember(start, "Miharu", serialNum++);
PrintMember(start);
free(start);
return 0;
}
MEMBER* NewMember(char* namae, int num){
MEMBER* this;
this = (MEMBER*)malloc(sizeof(MEMBER)); //allocate the memory
strcpy(this->name, namae); //copy the name
this->number = num;
this->next = NULL; //The next is NULL
return(this);
}
void AddMember(MEMBER* start, char* namae, int num){
MEMBER* p=start;
while(p!=NULL) p = p->next;
p = (MEMBER*)malloc(sizeof(MEMBER));
strcpy(p->name, namae);
p->number = num;
p->next = NULL;
}
void PrintMember(MEMBER* start)
{
MEMBER* p;
for(p=start; p!=NULL; p=p->next){
printf("%s %dn", p->name, p->number);
}
}
在你的AddMember函数中,你不修改列表中的最后一个元素来指向新元素,所以永远不会创建链表
在添加新的
之前修改最后一个元素还确保为malloc包含stdlib.h,因为不应该强制转换malloc()
void AddMember(MEMBER* start, char* namae, int num)
{
MEMBER* p=start;
MEMBER* q=NULL;
while(p!=NULL)
{
q = p;
p = p->next;
}
p = malloc(sizeof(MEMBER));
strcpy(p->name, namae);
p->number = num;
p->next = NULL;
if ( q != NULL )
{
q->next = p;
}
}
add函数永远不会将链中的最后一个指针设置为正在分配的新节点。它只获取它的值(NULL),然后创建一个新节点,将其地址存储在一个本地指针p
中。然后,新分配的节点被填充数据,但仍然与原始列表分离。
有很多方法可以正确地做到这一点。我更喜欢下面的方法,因为它允许您对所有添加使用AddMember
,而不必像您目前所做的那样对第一个添加进行特殊处理。它使用指针对指针的方法:
void AddMember(MEMBER** start, char const* name, int num)
{
// loop until the pointer who's address is stored in
// the start parameter is NULL.
while (*start)
start = &(*start)->next;
// start now contains the address of the last pointer
// in our linked list. allocate a new node, saving the
// address in that pointer.
*start = NewMember(name, num);
}
还需要一种释放整个列表的机制;不只是第一个节点。free()
不行。同样,使用指针对指针:
void FreeMembers(MEMBER** start)
{
while (*start)
{
MEMBER *tmp = *start;
*start = tmp->next;
free(tmp);
}
}
在您的main()
中像这样调用:
int main()
{
static int serialNum=1;
MEMBER* start = NULL; // Note: MUST be NULL on inception.
AddMember(&start, "Tugi", serialNum++);
AddMember(&start, "Bill", serialNum++);
AddMember(&start, "Sweet", serialNum++);
AddMember(&start, "Miharu", serialNum++);
PrintMember(start);
FreeMembers(&start);
return 0;
}
祝你好运。
因为你重写了最后一个链接,而不是设置它的下一个链。
因此,在第一次添加时,您将获得Tugi
,然后将其替换为后面的一个。需要将p->next
设置为新建的链接。
找到最后一个链接(p
)后,创建一个新链接(new_p
),然后在末尾执行:p->next = new_p;
(实际上是将新链接添加到末尾)。