Найти максимальное число для поля в массиве студентов - PullRequest
0 голосов
/ 17 февраля 2019

Я хочу найти максимальное число среди студентов, данные уже приведены с использованием указателя и структуры из десяти студентов.

Моя программа дает неправильный ответ.

Я новичок в программировании, может кто-нибудь сказать мне, что не так с этой программой?

#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 голосов
/ 17 февраля 2019

В вашем коде несколько проблем:

  • Вы вычисляете количество элементов в st с помощью SIZE = sizeof(st) / 34;.Это неверно, потому что размер struct student вряд ли будет 34: скорее всего, между элементами name и rollno есть некоторые отступы для обеспечения правильного выравнивания элементов int.Вы не должны полагаться на вычисленные вручную магические значения, подобные этим, просто используйте SIZE = sizeof(st) / sizeof(st[0]);, который работает для всех типов массивов.

  • функция maximum должна быть объявленаили определено перед использованием.

  • Вы должны проверить возвращаемое значение scanf("%d", &b);, чтобы избежать неопределенного поведения для неверного ввода: scanf() вернет EOF, если входной поток пуст и0, если он не может преобразовать число из содержимого потока, оставляя b неизмененным и, следовательно, неинициализированным.

  • инициализация локальной переменной в блоке switch, так как int maximum = 0; имеетнет эффекта.Код инициализации игнорируется, так как switch ответвляется непосредственно к соответствующему case.Это основная ошибка, вызывающая вашу проблему, она довольно тонкая, и настройка компилятора для предупреждения о таких проблемах является разумной.Используйте gcc -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 кажется лучшим выбором.

Вот исправленная версия:

#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 maximum(const struct student *ptr, int count);

int main() {
    struct student st[] = {
        { 'ali', 3, 89, 76, 65, 45, 90 },
        { 'ma', 9, 87, 67, 90, 54, 45 },
        { 'la', 6, 78, 65, 43, 29, 342 },
    };
    int max = maximum(&st, sizeof(st) / sizeof(st[0]));

    if (max >= 0) {
        printf("%d\n", max);
    }
    return 0;
}

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

    if (count <= 0) {
        printf("there are no student records\n");
        return -1;
    }
    printf("enter number for subject\n");
    printf("  enter 1 for DS:\n");
    printf("  enter 2 for machine:\n");
    printf("  enter 3 for ADE:\n");
    printf("  enter 4 for signal system:\n");
    printf("  enter 5 for math:\n");
    if (scanf("%d", &b) != 1) {
        printf("invalid input\n");
        return -1;
    }

    switch (b) {
        case 1: {
            maximum = ptr[0].DS_marks;
            for (i = 1; i < count; i++) {
                if (maximum < ptr[i].DS_marks) {
                    maximum = ptr[i].DS_marks;
                }
            }
            break;
        }
        case 2: {
            maximum = ptr[0].machine_marks;
            for (i = 1; i < count; i++) {
                if (maximum < ptr[i].machine_marks) {
                    maximum = ptr[i].machine_marks;
                }
            }
            break;
        }
        case 3: {
            maximum = ptr[0].ADE_marks;
            for (i = 1; i < count; i++) {
                if (maximum < ptr[i].ADE_marks) {
                    maximum = ptr[i].ADE_marks;
                }
            }
            break;
        }
        case 4: {
            maximum = ptr[0].signal_system_marks;
            for (i = 1; i < count; i++) {
                if (maximum < ptr[i].signal_system_marks) {
                    maximum = ptr[i].signal_system_marks;
                }
            }
            break;
        }
        case 5: {
            maximum = ptr[0].math_marks;
            for (i = 1; i < count; i++) {
                if (maximum < ptr[i].math_marks) {
                    maximum = ptr[i].math_marks;
                }
            }
            break;
        }
        default: {
            printf("you have entered an invalid number\n");
            break;
        }
    }
    return maximum;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...