从结构体数组筛选前三名学生的C语言代码问题咨询
结构体成员赋值问题与代码修正
问题描述
用户的疑问:
- 原代码中可以将
studs[i].score赋值给first.score这类结构体成员,但studs[i].name = first.name这类语句无法编译,原因是什么? - 同时原代码逻辑存在错误,无法正确找出前三名学生。
原代码如下:
#include<stdio.h> #include<stdlib.h> #include<string.h> struct stud { char name[50]; float score; }; //Please do not modify struct stud //You are only allowed to modify inside printThreeLeaders void printThreeLeaders(struct stud studs[], int count) { //why is count here? C arrays do not carry any size indicator, we //must explicitly pass the number of elements in as an argument //Please do not modify the content of studs array struct stud first, second, third; //Your code here for (int i=0;i<count;i++){ if (studs[i].score>third.score){ if(studs[i].score>second.score){ if (studs[i].score>first.score){ studs[i].score=first.score; studs[i].name=first.name; } }studs[i].score=second.score; studs[i].name=second.name; }studs[i].score=third.score; studs[i].name=third.name; } //Please find the top three highest scoring students on the leaderboard //and print out their names and scores. //You are allowed to use string functions such as strcmp or strcpy //Although you might not need them //Please do not modify the following code printf("Leader board:\n"); printf("First place: %s, %.2f\n", first.name, first.score); printf("Second place: %s, %.2f\n", second.name, second.score); printf("Third place: %s, %.2f\n", third.name, third.score); } //Please do not modify main function int main(void) { struct stud students[20]; int stud_count = 0; char temp_name[50]; float grade = 0; printf("Enter a test score(-1 to quit), or\n"); printf("Enter a grade first, then a student's name\n"); scanf("%f", &grade); while (grade != -1) { scanf("%s", temp_name); students[stud_count].score = grade; strcpy(students[stud_count].name, temp_name); stud_count ++; printf("Enter a test score(-1 to quit), or\n"); printf("Enter a grade first, then a student's name\n"); scanf("%f", &grade); } if(stud_count > 2) { printThreeLeaders(students, stud_count); } return 0; }
问题解答
1. 赋值差异的根本原因
score成员可以直接赋值:score是float类型,属于C语言的基本数据类型,这类类型的变量存储的是实际数值,因此可以直接通过=完成赋值操作,本质是把一个变量的数值拷贝到另一个变量的内存空间中。name成员不能直接用=赋值:name是char[50]字符数组,在C语言中,数组名代表数组首元素的地址常量,它的值是固定的,不能被修改。studs[i].name = first.name试图把一个地址赋值给另一个地址常量,违反语法规则,因此编译报错。要复制字符数组的内容,必须使用strcpy函数,该函数会把源数组中的每个字符逐一拷贝到目标数组的内存空间中。
2. 原代码的逻辑错误修正
原代码存在多个问题:
- 赋值方向完全颠倒:应该把当前学生的信息赋值给
first/second/third,而不是反过来修改studs数组(题目明确要求不能修改studs数组内容)。 - 未初始化
first/second/third的score:未初始化的结构体成员会包含垃圾值,导致比较逻辑失效,需要初始化为极小值(比如-1.0,因为分数不会是负数)。 - 条件分支的缩进错误:导致逻辑判断混乱,无法正确更新前三名的顺序。
修正后的printThreeLeaders函数代码如下:
void printThreeLeaders(struct stud studs[], int count) { // 初始化前三名的分数为极小值,确保第一个学生能被正确选中 struct stud first = {"", -1.0f}; struct stud second = {"", -1.0f}; struct stud third = {"", -1.0f}; for (int i = 0; i < count; i++) { if (studs[i].score > first.score) { // 当前分数超过第一名,把原第一名降级为第二名,原第二名降级为第三名 third = second; second = first; // 复制当前学生的信息到第一名 first.score = studs[i].score; strcpy(first.name, studs[i].name); } else if (studs[i].score > second.score) { // 当前分数超过第二名,原第二名降级为第三名 third = second; // 复制当前学生的信息到第二名 second.score = studs[i].score; strcpy(second.name, studs[i].name); } else if (studs[i].score > third.score) { // 当前分数超过第三名,直接复制信息到第三名 third.score = studs[i].score; strcpy(third.name, studs[i].name); } } // 以下代码保持不变 printf("Leader board:\n"); printf("First place: %s, %.2f\n", first.name, first.score); printf("Second place: %s, %.2f\n", second.name, second.score); printf("Third place: %s, %.2f\n", third.name, third.score); }
修正说明
- 初始化前三名的
score为-1.0f,确保所有有效分数(非负)都能参与比较。 - 按照分数从高到低的顺序,依次更新前三名的信息,每次更新时都通过
strcpy复制名字,用直接赋值复制分数。 - 严格遵循题目要求,没有修改
studs数组的内容。
内容的提问来源于stack exchange,提问作者JEDi455
相关产品推荐
相关产品推荐

