这是我写的代码:
#include<stdio.h>
#define STARHEAD "*******************************************************\n"
#define SHOWHEAD " Show information for all students \n"
#define SORTHEAD " Output from high to low according to grades \n"
#define WRAPHEAD "\n"
struct Student {
int number;
char name[15];
int score;
};
struct Student student[10] = {
{8, "imz", 84},
{30, "pzh", 30},
{28, "xhx", 88},
{51, "vbi", 81},
{35, "spe", 91},
{14, "apm", 77},
{7, "lyv", 71},
{9, "fey", 87},
{16, "uvv", 100},
{42, "aap", 67}
};
void show();
void sort();
void show()
{
int n;
printf(STARHEAD);
printf(SHOWHEAD);
printf(STARHEAD);
for (n = 0; n < 10; n++) {
printf("number:%2d name:%s score:%d\n", student[n].number, student[n].name, student[n].score);
}
printf(WRAPHEAD);
}
void sort()
{
int i, j, h, k;
struct Student temp;
printf(STARHEAD);
printf(SORTHEAD);
printf(STARHEAD);
for (i = 0; i < 9; i++) {
k = i;
for (j = i + 1; j < 10; j++) {
if (student[k].score < student[j].score) {
k = j;
temp = student[i];
student[k] = temp;
student[i] = student[k];
}
}
}
for (h = 9; h >= 0; h--) {
printf("number:%d name:%s score:%d\n", student[h].number, student[h].name, student[h].score);
}
}
int main()
{
show();
sort();
return 0;
}
本以为程序的输出是根据成绩来的,结果和我预想的不一样。这段代码我想了很久。很明显,逻辑上没有错误,和书上的源码差不多,但是结果并不能像我预想的那样输出
首先,交换的算法是错误的。你的算法
temp = student[i];
student[k] = temp;
student[i] = student[k];
相当于
student[k] = student[i];
你应该做的:
temp = student[i];
student[i] = student[k];
student[k] = temp;
其次,排序的算法是错误的。您可以执行排序,例如,通过固定一个位置来比较和存储最大(或最小)元素。
可以这样实现:
for (i = 0; i < 9; i++) {
for (j = i + 1; j < 10; j++) {
// move largest element to the front of current range
if (student[i].score < student[j].score) {
temp = student[i];
student[i] = student[j];
student[j] = temp;
}
}
}
// print from high score to low score
for (h = 0; h < 10; h++) {
printf("number:%d name:%s score:%d\n", student[h].number, student[h].name, student[h].score);
}
快速浏览一下您的代码,这些行让我印象深刻:
temp = student[i];
student[k] = temp;
student[i] = student[k];
看来您正在将
temp
设置为student[i]
。然后,以下行将 student[k]
设置为 temp
,等于 student[i]
。最后,您将 student[i]
设置为 student[k]
,等于 student[i]
。
有效地你这样做:
student[i] = student[i]
我相信你想要的是这个:
temp = student[i];
student[i] = student[k];
student[k] = temp;
这将有效地交换
student[k]
和student[i]
的值。至少这是我最好的猜测,我不知道你得到的输出到底是什么,或者你期望的输出是什么。
让我们看看你交换学生的三行:
temp = student[i];
student[k] = temp;
student[i] = student[k];
您首先指定
temp
与学生i
相同,因此temp
和i
相同而k
不同。然后你将学生k
设置为与temp
相同。在这一点上,他们三个都是一样的。
尝试交换两行:
student[k] = temp;
student[i] = student[k];
致:
student[i] = student[k];
student[k] = temp;
接下来在交换上方的检查中,您使用
k
作为其中一名学生的索引,并且该 k
值已设置为 i
的值,但 k
在检查中重新分配,以供使用为了不同的东西。使用i
代替,所以来自:
for (i = 0; i < 9; i++) {
k = i;
for (j = i + 1; j < 10; j++) {
if (student[k].score < student[j].score) {
致:
for (i = 0; i < 9; i++) {
for (j = i + 1; j < 10; j++) {
if (student[i].score < student[j].score) {
通过这些更改,结果变为:
在这里运行:https://ideone.com/GDJzTu
*******************************************************
Show information for all students
*******************************************************
number: 8 name:imz score:84
number:30 name:pzh score:30
number:28 name:xhx score:88
number:51 name:vbi score:81
number:35 name:spe score:91
number:14 name:apm score:77
number: 7 name:lyv score:71
number: 9 name:fey score:87
number:16 name:uvv score:100
number:42 name:aap score:67
*******************************************************
Output from high to low according to grades
*******************************************************
number:30 name:pzh score:30
number:42 name:aap score:67
number:7 name:lyv score:71
number:14 name:apm score:77
number:51 name:vbi score:81
number:8 name:imz score:84
number:9 name:fey score:87
number:28 name:xhx score:88
number:35 name:spe score:91
number:16 name:uvv score:100
在嵌套的 for 循环中使用变量
k
是多余和错误的。
在这个 if 语句中
if (student[k].score < student[j].score) {
k = j;
temp = student[i];
student[k] = temp;
student[i] = student[k];
}
变量
k
总是指向元素的值与元素的初始值student[i]
.
另外交换操作也不正确。在这两个声明之后
temp = student[i];
student[k] = temp;
student[k]
和 student[i]
彼此相等。所以这个声明
student[i] = student[k];
实际上等同于
student[i] = student[i];
相反你可以写
for (i = 0; i < 9; i++) {
for (j = i + 1; j < 10; j++) {
if (student[i].score < student[j].score) {
temp = student[i];
student[i] = student[j];
student[j] = temp;
}
}
}
注意函数依赖全局变量是不好的设计
数组
student
应该在main中声明。
此外,由于函数 sort 是一个通用函数,它还应该有一个参数来指定传递的数组中元素的数量,并且应该在函数中使用此参数而不是幻数 9。
如果只交换一次数组的元素,函数会更有效率。
此外,该函数只做一件事:对数组进行排序。要输出排序数组,您应该使用另一个函数。
函数可以看成下面的样子
void sort( struct Student student, size_t n )
{
for ( size_t i = 0; i < n; i++ )
{
size_t pos = i;
for ( size_t j = i + 1; j < n; j++ )
{
if ( student[pos].score < student[j].score )
{
pos = j;
}
}
if ( i != pos )
{
struct Student temp = student[i];
student[i] = student[pos];
student[pos] = temp;
}
}
}
函数在主函数中被调用
sort( student, 10 );