Итоги четверти
Добро пожаловать на последний урок курса C! Здесь вы соберёте вместе всё, чему научились, и шаг за шагом напишете одну полезную программу: итоги по математике для целого класса за четверть. За четверть класс написал три теста, и для табеля учителю нужны средний балл и оценка каждого ученика. Когда вы закончите, программа будет выводить такие результаты:
Max нет в классе.
ИТОГИ ПО МАТЕМАТИКЕ
Adam 42 38 45 41.7 B
Emma 36 33 38 35.7 C
Finn 50 50 50 50.0 A
Jack 17 25 20 20.7 D
Lucy 35 40 41 38.7 B
Лучший: Finn (среднее 50.0)
Среднее по классу: 37.3Программа выводит таблицу с баллами, средним баллом и оценкой каждого ученика, находит лучшего ученика, добавляет бонусные баллы и исправляет ошибку в баллах одного из учеников. Вы будете использовать переменные, условия, циклы, массивы, строки, функции, указатели и структуры: всё, что было в курсе. Каждое упражнение продолжает предыдущее (в редакторе уже лежит готовый код) и добавляет одну часть.
Данные. Каждый ученик — это структура типа Student с именем и массивом баллов за три теста (за каждый тест можно получить не больше 50 баллов). Ученики лежат в массиве students в начале main(). У каждого из них по две пары фигурных скобок: внешние относятся ко всему ученику, внутренние — к массиву points. Запятая после последнего ученика — не ошибка: C это разрешает, и так проще добавить ещё одного. Поэтому students[0].name — это "Adam", а students[0].points[2] — его результат за третий тест, 45. В переменной count хранится число учеников. Оно вычисляется с помощью sizeof, поэтому остаётся верным, даже когда вы добавите ученика. В настоящей школе данные приходили бы из школьной электронной системы. Здешние программы берут данные из переменных.
План. Программа разделена на функции, и у каждой одна задача. Пока функция одна: print_report(), она получает массив учеников и их число. Сейчас она выводит только заголовок. Она стоит над main(), потому что функцию нужно объявить до того, как её вызовут. Так обычно выглядит программа на C: сверху структура, под ней функции, а внизу — main(), который ими пользуется.
Параметр const Student students[] — это адрес массива из main() (то же самое, что const Student *students), поэтому ничего не копируется. Благодаря const функция только читает учеников, а для вывода больше ничего и не нужно.
Каждого ученика вы выведете в одной строке по частям: сначала имя, потом баллы во внутреннем цикле и, наконец, \n. Ширины выравнивают столбцы: %-10s дополняет имя пробелами до 10 символов (- прижимает имя влево), а %4d выводит число, прижатое вправо, в 4 символах. Например, футболисты и их голы в трёх матчах:
#include <stdio.h>
typedef struct {
char name[20];
int goals[3];
} Player;
int main(void) {
Player team[] = {
{"Tom", {2, 0, 1}},
{"Sara", {1, 3, 0}},
};
for (int i = 0; i < 2; i++) {
printf("%-6s", team[i].name);
for (int j = 0; j < 3; j++) {
printf("%3d", team[i].goals[j]);
}
printf("\n");
}
return 0;
}Tom 2 0 1
Sara 1 3 0Условие — i < count, а не <=. Последний индекс равен count - 1, поэтому с <= цикл полез бы за учеником, которого в массиве нет, и программа остановилась бы с RuntimeError: unreachable.
Задание
- 1
В
print_report()под строкой, которая выводит заголовок, напишите циклforс переменнойi, которая начинается с0и растёт, покаiменьшеcount. В цикле выводите имя каждого ученика с помощьюprintf("%-10s", students[i].name);, а под этой строкой завершите строку вывода:printf("\n");. Имена появятся каждое на своей строке. - 2
Между этими двумя вызовами
printfдобавьте внутренний циклforс переменнойj, который работает, покаjменьше3(три теста). В нём выводите баллы ученикаstudents[i].points[j]с помощью%4d, без\n. Программа выведет:ИТОГИ ПО МАТЕМАТИКЕ Adam 42 38 45 Emma 36 33 38 Finn 48 50 47 Jack 14 22 17 Lucy 27 40 41