我是C编程的初学者。我有一个任务创建一个使用双链表的学生列表。该应用程序应该有三点:显示列表,添加新学生并通过他的ID号删除学生。 我做到了,它运行得很好。 我想问几个问题:
这是我的代码:
struct student
{
char first_name[20];
char last_name[20];
char ID_NO[14];
struct student* previous;
struct student* next;
};
void Menu();
void Show_List(struct student*);
struct student* Add_Student(char [], char [], char [], struct student*);
struct student* Erase_Student(char [], struct student*);
void main(void)
{
char student_first_name[20];
char student_last_name[20];
char personal_code[14];
struct student* first = NULL;
struct student* node0 = NULL;
int x = 0;
int opt;
Menu();
for(; ;)
{
printf("\nEnter the operation you want to do: \n");
scanf("%d", &opt);
switch(opt)
{
case 1:
Show_List(first);
break;
case 2:
printf("\nEnter the student's first name: ");
scanf("%s", &student_first_name);
printf("\nEnter the student's last name: ");
scanf("%s", &student_last_name);
printf("\nEnter the student's personal code: ");
scanf("%s", &personal_code);
node0 = Add_Student(student_first_name, student_last_name, personal_code, first);
first = node0;
break;
case 3:
printf("\nEnter the code of the student you want to erase: ");
scanf("%s", &personal_code);
node0 = Erase_Student(personal_code, first);
first = node0;
break;
default:
printf("\nYou entered an invalid option!!! Please try again.\n");
Menu();
break;
}
}
scanf("%d", &x);
}
void Menu()
{
printf("\nSelect from the Menu the operation you want to execute:\n");
printf("\n1) Show students list;");
printf("\n2) Add a student in the list;");
printf("\n3) Erase a student from the list.");
}
void Show_List(struct student* firstNode)
{
struct student* firstNodeCopy = firstNode;
int number = 0;
if(firstNode == NULL)
printf("\nThe list is empty.\n");
while(firstNodeCopy)
{
printf("\n%d. %s ", ++number, firstNodeCopy->first_name);
printf("%s %s\n", firstNodeCopy->last_name, firstNodeCopy->ID_NO);
firstNodeCopy = firstNodeCopy->next;
}
}
struct student* Add_Student(char name_1[], char name_2[], char ID[], struct student* firstNode)
{
struct student* start = firstNode;
struct student* last = NULL;
struct student* addNode = (struct student*) malloc(sizeof(struct student));
if(firstNode == NULL)
{
firstNode = (struct student*) malloc(sizeof(struct student));
strcpy(firstNode->first_name, name_1);
strcpy(firstNode->last_name, name_2);
strcpy(firstNode->ID_NO, ID);
firstNode->next = NULL;
firstNode->previous = NULL;
return firstNode;
}
else
{
strcpy(addNode->first_name, name_1);
strcpy(addNode->last_name, name_2);
strcpy(addNode->ID_NO, ID);
while(start)
{
if(strcmp(addNode->first_name, start->first_name) > 0)
{
if(start->next == NULL)
{
start->next = addNode;
addNode->previous = start;
addNode->next = NULL;
return firstNode;
}
else
{
last = start;
start = start->next;
}
}
if(strcmp(addNode->first_name, start->first_name) < 0)
{
if(last == NULL)
{
addNode->next = start;
start->previous = addNode;
return addNode;
}
else
{
addNode->next = start;
addNode->previous = last;
last->next = addNode;
start->previous = addNode;
return firstNode;
}
}
if(strcmp(addNode->first_name, start->first_name) == 0)
{
if(strcmp(addNode->last_name, start->last_name) < 0)
{
if(last == NULL)
{
addNode->next = start;
start->previous = addNode;
return addNode;
}
else
{
addNode->next = start;
addNode->previous = last;
last->next = addNode;
start->previous = addNode;
return firstNode;
}
}
if(strcmp(addNode->last_name, start->last_name) > 0)
{
if(start->next == NULL)
{
start->next = addNode;
addNode->previous = start;
addNode->next = NULL;
return firstNode;
}
else
{
last = start;
start = start->next;
}
}
if(strcmp(addNode->last_name, start->last_name) == 0)
{
if(last == NULL)
{
addNode->next = start;
start->previous = addNode;
return addNode;
}
else
{
addNode->next = start;
addNode->previous = last;
last->next = addNode;
start->previous = addNode;
return firstNode;
}
}
}
}
}
}
struct student* Erase_Student(char ID[], struct student* firstNode)
{
struct student* start = firstNode;
struct student* last = NULL;
if(start == NULL)
{
printf("\nThe list is empty.\n");
return NULL;
}
else
{
while(start)
{
if(strcmp(ID, start->ID_NO) == 0)
{
if(last == NULL)
{
start = start->next;
return start;
}
else
{
last->next = start->next;
return firstNode;
}
}
else
{
last = start;
start = start->next;
}
}
printf("\nYou entered a WRONG personal ID number to erase!!! Please try again.\n");
return firstNode;
}
}
答案 0 :(得分:2)
free()
已删除的节点。int compareStudents(char * LeftFirstName, char * LeftLastName, char * RightFirstName, char * RightLastName);
除此之外,逻辑很好。
答案 1 :(得分:0)
你做得非常好!干得好,一开始!继续学习。
答案 2 :(得分:0)
这实际上非常好!在你介绍之后,我承认一团糟,我承认。
你在那里做得很好,伙计。无论你能改进什么,你都会在适当的时候学习:)。继续这样工作!
我打算建议你查看“抽象数据类型”是什么,以及如何公开界面模糊实现,但正如我所说 - 你很快就会学到它!
干杯。
答案 3 :(得分:0)
快速查看Add_Student(...)函数。看起来像一个小内存泄漏。如果你愿意,我可以更具体,但你认为你可能想要练习。
答案 4 :(得分:0)
scanf("%19s", &student_first_name);
答案 5 :(得分:0)
您选择多个变量名称会使代码不必要地混淆。例如,在Show_List
中,您有一个名为firstNodeCopy
的东西,它不是任何节点的副本,并不总是引用第一个节点。
在Add_Student
,你有很多不同的比较,我甚至不确定你甚至想要完成什么,但我很确定你所拥有的是可以改进的。同样,你有一些变量(例如,start
),这些变量的名称似乎并不是他们真正应该做的事情的真实指示。
我建议稍微更改结构:创建一个函数compare_students
(或类似的东西)只是处理一个学生与另一个学生的比较,并(例如)告诉你两名学生A和B是否有序或无序。我可能还会添加一个“创建学生”来获取一组输入并从中创建学生结构。从那里,插入算法看起来像:
if list is empty, put new node in list
if new node precedes first item in list, insert at head of list
Walk through list until end of list or current node precedes new node
if at end of list, add new node to end
else insert new node before current node
答案 6 :(得分:0)
我找到的一些挑剔
#include
:在此计划中,您需要<stdio.h>
,<stdlib.h>
和<string.h>
enum
或#define
而非使用“魔数”缩小你的来源scanf
和检查返回值 '\n'
:printf("...\n")
vs printf("\n...")
strcmp
s 编辑推送到MAX的警告级别,并尝试删除所有警告。
答案 7 :(得分:0)
您可以将void Menu()
的原型更改为void Menu(void)
。这样编译器可以检查函数是否被正确调用。如果在编译时已经发现错误总是好的。