windows 为什么会发生这种情况?[关闭]

kokeuurv  于 2023-03-09  发布在  Windows
关注(0)|答案(4)|浏览(305)

**已关闭。**此问题需要debugging details。当前不接受答案。

编辑问题以包含desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem。这将有助于其他人回答问题。
昨天关门了。
Improve this question
下面是我写的代码:

#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;
}

本以为程序的输出是以成绩为依据的,结果却和我预想的不一样,这段代码我想了很久,显然逻辑上没有错误,和书中的源代码差不多,但结果却不能如我所料输出。

zaq34kh6

zaq34kh61#

首先,交换的算法是错误的。你的算法

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);
}
bf1o4zei

bf1o4zei2#

快速浏览一下您的代码,下面几行代码让我印象深刻:

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]的值,至少这是我最好的猜测,我不知道你得到的输出是什么,或者你期望的输出是什么。

63lcw9qa

63lcw9qa3#

让我们看看你交换学生的三行:

temp = student[i];
            student[k] = temp;
            student[i] = student[k];

首先指定temp与学生i相同,因此tempi相同而k不同,然后将学生k设置为与temp相同,此时三者都相同。
尝试交换这两行:

student[k] = temp;
            student[i] = student[k];

收件人:

student[i] = student[k];
            student[k] = temp;

接下来,在交换上面的检查中,您使用k作为其中一个学生的索引,该k值已设置为i,但k在检查中被重新分配,以用于其他用途。

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
pgky5nke

pgky5nke4#

在嵌套的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是一个通用函数,它应该有一个指定所传递数组中元素数量的参数(除了表示所传递数组的参数之外),并且该参数应该在函数中使用,而不是幻数910
如果在外部循环中仅交换数组元素一次,则函数将更高效。
此外,该函数只能做一件事:对数组进行排序。要输出排序后的数组,应该使用其他函数。
该函数可以如下所示

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;
        }
    }
}

函数在main中调用,如

sort( student, 10 );

相关问题