在一组学生中查找字段的最大数目

时间:2019-02-17 09:06:54

标签: c

我想找到最大的学生人数,数据已经使用指针和十个学生的结构给出。

我的程序给出了错误的答案。

我是编程初学者,有人可以告诉我该程序有什么问题吗?

#include <stdio.h>

struct student
{
    char name[10];
    int rollno;
    int DS_marks;
    int machine_marks;
    int ADE_marks;
    int signal_system_marks;
    int math_marks;
};

int main()
{
    int SIZE;

    struct student st[] = {
        { 'ali', 3, 89, 76, 65, 45, 90},
        { 'ma', 9, 87, 67, 90, 54, 45},
        { 'la', 6, 78, 65, 43, 29, 342}
    };

    // student structure pointer variable
    struct student *ptr;
    ptr = &st;
    SIZE = sizeof(st) / 34;
    if (SIZE == 0)
    {
        printf("there is no student record");
    }
    else
    {
        int max = maximum(ptr, SIZE);
        printf("%d", max);
    }
    return 0;
}

int maximum(struct student *ptr, int SIZE)
{
    int b, i;

    printf("press number for subject\n ");
    printf("press 1 for DS:\n ");
    printf("press 2 for machine:\n ");
    printf("press 3 for ADE:\n ");
    printf("press 4 for signal system:\n ");
    printf("press 5 for math:\n ");
    scanf("%d", &b);

    switch (b)
    {
        int maximum = 0;
        case 1:
        {
            for (i = 0; i < SIZE; i++)
            {
                if ((*ptr).DS_marks > maximum)
                {
                    maximum = (*ptr).DS_marks;
                }
                ++ptr;
            }
            break;
        }
        case 2:
        {
            for (i = 0; i < SIZE; i++)
            {
                if ((*ptr).DS_marks > maximum)
                {
                    maximum =(*ptr).machine_marks;
                }
                ++ptr;
            }
            break;
        }
        case 3:
        {
            for (i = 0; i < SIZE; i++)
            {
                if ((*ptr).ADE_marks > maximum)
                {
                    maximum =(*ptr).ADE_marks;
                }
                ++ptr;
            }
            break;
        }
        case 4:
        {
            for (i = 0; i < SIZE; i++)
            {
                if ((*ptr).signal_system_marks > maximum)
                {
                    maximum =(*ptr).signal_system_marks;
                }
                ++ptr;
            }
            break;
        }
        case 5:
        {
            for (i = 0; i < SIZE; i++)
            {
                if ((*ptr).math_marks > maximum)
                {
                    maximum =(*ptr).math_marks;
                }
                ++ptr;
            }
            break;
        }
        default:
        {
            printf("you have pressed wrong number");
            break;
        }
    }
    return maximum;
}

1 个答案:

答案 0 :(得分:0)

您的代码中存在多个问题:

  • 您可以使用st计算SIZE = sizeof(st) / 34;中的项目数。这是不正确的,因为struct student的大小不太可能是34namerollno成员之间很可能会有一些填充以确保{的正确对齐{1}}个成员。您不应该依赖这样的手工计算的 magical 值,只需使用int(适用于所有数组类型)即可。

  • 函数SIZE = sizeof(st) / sizeof(st[0]);应该在使用前声明或定义。

  • 您应检查maximum的返回值,以避免无效输入的未定义行为:如果输入流为空且scanf("%d", &b);,则scanf()将返回EOF如果无法从流内容转换数字,则0保持不变,因此未初始化。

  • b块中的局部变量初始化为switch无效。由于int maximum = 0;直接分支到适当的switch,所以绕过了初始化代码。这是导致问题的主要错误,它非常微妙,配置编译器以警告此类问题是明智的。使用casegcc -Wall -Wextra -Werror可以避免愚蠢的错误。将定义和初始化移到clang -Wall -Wextra -Werror语句之外。

  • 您假定所有字段均为正值。如果对所有值都为负的成员应用相同的算法,则可能会导致问题。将switch替换为第一个字段的值而不是maximum即可解决。

  • 0中的
  • 中,您测试了错误的成员:case 2而不是if ((*ptr).DS_marks > maximum)。剪切/粘贴/修改错误的经典案例。用if ((*ptr).machine_marks > maximum)编写测试将有助于避免这样的错误,因为现场成员出现在直线上的相同位置:眼睛会立即发现缺乏对称性。实际上,我只是在重写代码以提高可读性之后才发现此错误(请参见下文)。

  • 输出应以换行符{<等终止。

  • 这不是错误,但是printf("%d\n", max);的可读性更像是(*ptr).DS_marks

  • 并非错误,但是所有大写标识符(例如ptr->DS_marks)都应保留给宏和预定义的常量。在这种情况下,SIZE似乎是更好的选择。

这是更正的版本:

count