C 编程中链表中的应用程序



问题在下面 下面的结构表示有关学生及其成绩列表的信息 所有模块。

typedef struct {
char* module; //module, e.g. "COMP1028"
int grade; //numerical grade
} module_grade;
typedef struct {
unsigned int student_ID;
char* student_name;
module_grade* grades; //array of grades
unsigned int grades_len; //length of the array grades
} student;

您需要实现三个功能来管理学生的成绩。 a) 编写一个名为create_student_list的 C 函数,该函数采用学生姓名 和学生 ID 并返回指向new_student的指针。的等级new_student将初始化为NULLgrade_len设置为0。 该函数的定义是:student* create_student_list (char* stu_name, int stu_id) {

b) 编写一个 C 函数search_grade,该函数将指针指向学生和模块 并返回此模块的学生成绩。如果等级数组是NULL或模块不在等级数组中,则该函数应返回-1。 该函数的定义是:int search_grade(student* s, char* module) {

c) 编写一个 C 函数adding_grade,该函数将指针指向学生和模块 评分并将成绩添加到学生的成绩数组中。 如果student->grades已经包含类似的模块,则该函数不执行任何操作。 如果student->grades==NULL,则需要创建一个长度1数组并添加 数组中的新等级。 如果student->grades!=NULL,则需要将数组的大小增加 ONE, 并将new_grade添加到成绩数组中的新条目中。 如果成功添加等级,应return 1该函数。否则, 功能应return 0;这可能是因为模块已经存在或malloc失败。 该函数的定义是:int adding_grade(student* s, module_grade new_grade)

在问题 a)我不明白他是否希望它是一个链表,所以我们需要一个循环,但我无法设法创建一个节点并将其链接在一起,所以我只将数据分配给指针,但它没有正确读取它。仅输出一个字符,而不是整个字符串。

typedef struct {
char* module; //module, e.g. "COMP1028"
int grade; //numerical grade
} module_grade;
typedef struct {
unsigned int student_ID;
char student_name[50];
module_grade* grades; //array of grades
unsigned int grades_len; //length of the array grades
} student;
student* create_student_list (const char *stu_name, int stu_id);

int main(){
student Student;
module_grade Module;
printf("enter the student name?t");
scanf("%s",Student.student_name);
printf("%s",Student.student_name);
printf("nenter the student ID?t");
scanf("%d",&Student.student_ID);
printf("%d",Student.student_ID);
create_student_list( &Student.student_name, Student.student_ID);
//search grade
printf("enter the module wanted to know the grade?");
scanf("%s",Module.module);
search_grade(&Student,Module.module);
return 0;
}
student* create_student_list (const char *stu_name, int stu_id) {
student student1 = {.student_ID = stu_id,.student_name = 
*stu_name};
student *newstudent = &student1;
printf("n%st%d",&newstudent->student_name,newstudent->student_ID);
newstudent->grades = NULL;
newstudent->grades_len = 0;
}

对于问题 B 和 C,我无法使其工作,因为我不知道我是否需要链表或如何将其与问题中的给定结构链接。

请我需要帮助,我的未来和大学的进步取决于它,所以我真的很感激任何答案或解释。

是否使用链表。

您是对的,类型为module_grade的对象可以存储为链表。但是,这将要求module_gradestruct定义包含指向下一个节点的指针,即struct定义必须更改为以下内容:

typedef struct module_grade
{
char* module;
int grade;
//pointer to the next node in the linked list
struct module_grade *next;
} module_grade;

但是,教师可能不希望您更改struct定义,因为使用教师提供的struct定义是作业的一部分。此外,在作业文本中,教师使用"数组"一词。这可能意味着studentstruct定义的grades成员应该指向数组的开头,而不是链表的第一个节点。

上述信息仅适用于存储module_grade对象。您的老师是否希望您将单个student对象存储在链表中是另一个问题。由于您在问题中提供的信息没有提供您需要创建多个student对象的任何指示,因此没有理由创建这样的链表。但是,我怀疑您的老师可能会要求您在以后的作业中创建这样的链表。

代码中的错误

函数main中的错误

该行

scanf("%s",Student.student_name);

将不起作用,因为scanf要求您传递指向内存缓冲区的内存地址的指针,该缓冲区有足够的空间来存储字符串。但是,您传递的指针不指向任何内容,因为它具有不确定的值。

为存储字符串分配足够内存的最简单方法是声明一个本地数组。

您在以下行中犯了相同的错误:

scanf("%s",Module.module);

另外,在行中

create_student_list( &Student.student_name, Student.student_ID);

传递&Student.student_name是错误的,因为这将传递指针Student.student_name的地址,但你想传递它的值。此外,您正在丢弃该函数调用的返回值,您也不应该这样做。相反,您应该使用它。

也不应该声明变量

student Student;

在函数main中,因为创建该对象是函数crate_student_list的责任。

为了修复这些错误,您可以使用以下代码:

int main()
{
char student_name[100];
int  student_ID;
char module_name[100];
student* p_student;
printf( "Enter the student name: " );
scanf( "99%s", student_name );
printf( "%sn", student_name );
printf( "Enter the student ID: ");
scanf( "%d", &student_ID );
printf( "%dn", student_ID );
p_student = create_student_list( student_name, student_ID );
if ( p_student == NULL )
{
fprintf( stderr, "Error creating student!n" );
exit( EXIT_FAILURE );
}
printf("enter the module wanted to know the grade?");
scanf( "%99s", module_name );
search_grade( p_student, module_name );
return 0;
}

请注意,我将匹配字符的数量限制为scanf99个字符,以便scanf不会尝试向任何缓冲区写入超过100个字符(99匹配字符加上终止 null 字符)。否则,如果用户输入太多字符,则会发生缓冲区溢出,这将调用未定义的行为(即程序可能会崩溃)。

还值得注意的是,在调用adding_grade之前调用search_grade没有多大意义,因为如果没有存储在Student中的成绩,那么搜索将始终失败。

函数中的错误create_student_list

函数create_student_list应该返回一个值。你可能忘了写

return newstudent;

在此函数的末尾。

但是,这是错误的,因为指针newstudent指向的对象student1的生存期将在函数返回后立即结束create_student_list因为您将其声明为具有自动存储持续时间的变量。因此,如果您在函数末尾返回指向该对象的指针,那么您将返回指向不再存在的对象的指针,即悬空指针。任何在函数main中取消引用此指针的尝试都将调用未定义的行为。

为了防止对象的生存期在函数返回时自动结束,不应将对象声明为局部变量。相反,您应该使用mallocfree来完全控制对象的生存期。

此外,您可能希望创建stu_name指向的字符串的副本。否则,如果包含此字符串的内存稍后被修改(例如用于其他内容),那么您将丢失该字符串。但是,如果student对象有自己的字符串副本,则不会发生这种情况。

因此,最好像这样编写函数create_student_list

student* create_student_list ( const char* stu_name, int stu_id )
{
//allocate memory for new_student
student* new_student = malloc( sizeof *new_student );
if ( new_student == NULL )
{
fprintf( stderr, "Warning: malloc failed!n" );
return NULL;
}
//set struct members except for student_name
new_student->student_ID = stu_id;
new_student->grades = NULL;
new_student->grades_len = 0;
//allocate memory for student_name and copy it
new_student->student_name = malloc( strlen(stu_name + 1 ) );
if ( new_student->student_name == NULL )
{
fprintf( stderr, "Warning: malloc failed!n" );
free( new_student );
return NULL;
}
strcpy( new_student->student_name, stu_name );
return new_student;
}

相关内容

  • 没有找到相关文章

最新更新