Поиск ученика
Lucy пришла жаловаться: учитель неправильно сложил её баллы за первый тест. Должно быть 35, а не 27. Программе нужна функция, которая исправляет баллы ученика по имени. Но сначала нужно найти ученика в массиве.
Поиск — знакомый шаблон: цикл идёт по ученикам и, найдя нужного, сразу возвращает указатель на него (return заодно завершает цикл). Если цикл закончился и никого не нашёл, функция возвращает NULL — указатель, который никуда не указывает. Имена сравнивают с помощью strcmp из string.h, которая возвращает 0 для одинакового текста:
#include <stdio.h>
#include <string.h>
typedef struct {
char name[20];
int price;
} Product;
Product *find_product(Product products[], int count, const char name[]) {
for (int i = 0; i < count; i++) {
if (strcmp(products[i].name, name) == 0) {
return &products[i];
}
}
return NULL;
}
int main(void) {
Product shop[] = {
{"Хлеб", 35},
{"Молоко", 24},
};
Product *milk = find_product(shop, 2, "Молоко");
if (milk != NULL) {
milk->price = 22;
}
printf("Молоко: %d\n", shop[1].price);
if (find_product(shop, 2, "Сыр") == NULL) {
printf("Сегодня сыра нет.\n");
}
return 0;
}Молоко: 22
Сегодня сыра нет.Функция возвращает &products[i] — адрес товара в массиве вызывающего кода, а не копию. Поэтому изменение milk->price изменило цену в shop. Параметр — Product products[] без const, потому что товар меняют через указатель, который функция возвращает.
Типичные ошибки:
students[i].name == nameсравнивает не тексты, а их адреса, поэтому никого не находит. Используйтеstrcmp.strcmpвозвращает0, когда тексты одинаковы, поэтому условие такое:strcmp(...) == 0. Без== 0оно истинно для каждого другого имени.- Без
#include <string.h>компилятор сообщаетerror: call to undeclared library function 'strcmp'.
А что, если учитель введёт имя, которого нет в массиве? Например, Max учится в параллельном классе. find_student() вернёт NULL, а запись student->points[test] через NULL остановила бы программу с RuntimeError: unreachable. Поэтому fix_points() проверяет указатель, прежде чем им пользоваться.
Задание
- 1
Добавьте
#include <string.h>под#include <stdio.h>. Затем подadd_bonus()напишите функциюStudent *find_student(Student students[], int count, const char name[]), которая возвращает указатель на ученика с именемnameилиNULL, если его нет в массиве. - 2
Под ней напишите функцию
void fix_points(Student students[], int count, const char name[], int test, int new_points). Она ищет ученика с помощьюfind_student(). Если получилаNULL, она выводит имя и слованет в классе.Для Max этоMax нет в классе.Иначе она записывает ученику в баллы за тест с индексомtestзначениеnew_points. - 3
В
main()над вызовомprint_report()исправьте первый тест Lucy (индекс0):fix_points(students, count, "Lucy", 0, 35);. Теперь у Lucy оценка B:Lucy 35 40 41 38.7 BЕсли у Lucy получилось
27 35 41, вы использовали индекс 1. У первого теста индекс 0. - 4
Попробуйте имя, которого нет в классе: под исправлением для Lucy добавьте
fix_points(students, count, "Max", 0, 40);. Над результатами появится строка:Max нет в классе.