修改后的代码:
问题1:输入指令为A B C等字符的时候会出去一直打印刷屏
问题2:在void insertPerson(struct Person **person)函数中 为什么要定义一个struct Person类型的add 给add分配内存空间 不能直接对*person操作吗? 直接对它进行分配内存空间再进行每个节点的赋值
问题3:void insertPerson(struct Person **person)和void delPerson(struct Person **person)中 为什么参数都是指针的指针 你说以便在删除第一个元素时能够更新 person 但是我还是有点不明白 是传进去地址是指针的地址 而不是头节点的地址吗? 对删除第一个元素有什么帮助呢? 能详细讲解一下思路逻辑吗?
问题4:最后释放内存的函数void releasePerson(struct Person **person)释放掉了每一个节点的内存 如果只释放头节点 比如1->2->3 释放掉1的内存空间后 链表还会以2->3存在吗? 2是否是变成了头节点了?#include<stdio.h>
#include <stdlib.h>
#include <string.h>
struct Person
{
char name[40];
char phone[20];
struct Person *next;
};
void welcome();
void getInput(struct Person *person);
void insertPerson(struct Person **person);
void printPerson(struct Person *person);
void findPerson(struct Person *person);
void changePerson(struct Person *person);
void delPerson(struct Person **person);
void displayContacts(struct Person *contacts);
void releasePerson(struct Person **person);
void getInput(struct Person *person)
{
printf("请输入姓名:");
scanf("%s",person->name);
printf("请输入电话:");
scanf("%s",person->phone);
}
void insertPerson(struct Person **person)
{
struct Person *add, *temp;
add = (struct Person*)malloc(sizeof(struct Person));
if(add == NULL) // 判断内存分配是否成功
{
printf("内存分配失败了!\n");
exit(1);
}
getInput(add);
if(*person == NULL)
{
*person = add;
add->next = NULL;
}
else
{
temp = *person;
*person = add; //为什么这里要有这句 因为下次main循环进来 不会执行
//条件为*person == NULL判断语句 *person就没有指向add的地址
add->next = temp;
}
}
void printPerson(struct Person *person)
{
printf("联系人:%s\n", person->name);
printf("电话:%s\n", person->phone);
}
void findPerson(struct Person *person)
{
struct Person *temp = person;
char n[128];
printf("请输入待查找联系人:");
scanf("%s",n);
while(temp)
{
if(strcmp(temp->name, n) == 0)
{
printPerson(temp);
}
temp = temp->next;
}
}
void changePerson(struct Person *person) //和答案有区别 这里代码臃肿了 本身可以调用查找函数再修改 这里的修改函数里又做了一次查找代码
{
struct Person *temp = person;
char n[128];
printf("请输入待修改联系人:");
scanf("%s",n);
while(temp)
{
if(strcmp(temp->name, n) == 0)
{
printf("请输入%s新的电话:",temp->name);
scanf("%s",temp->phone);
return;
}
temp = temp->next;
}
printf("未能找到联系人%s!\n",n);
}
void delPerson(struct Person **person)
{
struct Person *temp = *person;
struct Person *prev = NULL;
char n[128];
printf("请输入待删除联系人:");
scanf("%s",n);
while(temp)
{
if(strcmp(temp->name, n) == 0)
{
if(prev == NULL)//判断是不是第一次循环 第一次循环时prev才会==NULL
{
*person = temp->next;//这里直接对*person修改 因为要删除的是第一个节点
}
else//不是第一次循环(此时的temp不在第一个节点)
{
prev->next = temp->next;
}
free(temp);
printf("已删除联系人%s!\n",n);
return;
}
prev = temp;
temp = temp->next;
}
printf("未能找到联系人%s!\n",n);
}
void displayPerson(struct Person *person)
{
struct Person *current;
current = person;
while (current != NULL)
{
printPerson(current);
current = current->next;
}
}
void releasePerson(struct Person **person)
{
struct Person *temp;
while (*person != NULL)
{
temp = *person;
*person = (*person)->next;
free(temp);
}
}
void welcome()
{
printf("| 欢迎使用通讯录管理程序 |\n");
printf("|--- 1:插入新的联系人 ---|\n");
printf("|--- 2:查找已有联系人 ---|\n");
printf("|--- 3:更改已有联系人 ---|\n");
printf("|--- 4:删除已有联系人 ---|\n");
printf("|--- 5:显示当前通讯录 ---|\n");
printf("|--- 6:退出通讯录程序 ---|\n");
printf("|--- Powered by Psy ---|\n");
}
int main(void)
{
welcome();
struct Person *person = NULL;
struct Person *temp;
while(1)
{
int n;
printf("请输入指令代码:");
scanf("%d",&n);
if(n > 6 || n < 1)
{
printf("输入有误!");
continue;
}
else
{
switch(n)
{
case 1:insertPerson(&person);break;
case 2:findPerson(person);break;
case 3:changePerson(person);break;
case 4:delPerson(&person);break;
case 5:displayPerson(person);break;
case 6:goto END;
}
}
printf("\n\n");
}
END:
releasePerson(&person);
return 0;
}
|