Массивы и функции
Аргументом может быть и массив. Функция, получившая массив, может пройти по нему в цикле и, например,вернуть сумму его элементов:
#include <stdio.h>
int sum(int numbers[], int count) {
int total = 0;
for (int i = 0; i < count; i++) {
total += numbers[i];
}
return total;
}
int main(void) {
int points[] = {8, 5, 10};
int goals[] = {2, 0, 1, 3, 1};
printf("%d\n", sum(points, 3));
printf("%d\n", sum(goals, 5));
return 0;
}Эта программа выводит:
23
7Параметр int numbers[] — это массив значений int. Скобки у него пустые, потому чтофункция может получить массив любого размера. В вызове пишут только имя массива, без скобок:sum(points, 3). Со скобками, sum(points[], 3), программа не скомпилируется:error: expected expression.
Зачем нужен второй параметр, count? Функция не знает, сколько в массиве элементов, поэтому обэтом нужно сообщить ей. Не пытайтесь писать sizeof(numbers) / sizeof(numbers[0]) внутри функции:там numbers на самом деле не весь массив (что это такое, вы увидите в уроке об указателях), ипоэтому sizeof не считает его элементы. Clang лишь предупреждает об этом (а этот сайтпредупреждения не показывает), и количество получается неверным (здесь 1, так что функциясложила бы только первый элемент). Вычисляйте количество там, где массив был создан, в main, ипередавайте его функции. И следите, чтобы количество было правильным: при слишком большом количествефункция прочитала бы данные за концом массива, эту ошибку вы знаете по уроку о массивах.
Обратите внимание, где стоит return: после }, которая закрывает цикл, когда всеэлементы уже сложены. Частая ошибка — поставить его строкой выше, внутрь цикла. Тогда он завершил бы всюфункцию уже на первом проходе цикла. Здесь такая программа даже не компилируется:non-void function does not return a value in all control paths. При количестве 0 циклне выполнялся бы вообще, и функция дошла бы до конца без return.
Между массивами и числами есть одно большое различие. Параметр-число получает копию, как вы видели впредыдущем упражнении. Массив не копируется: функция получает тот самый массив, который передал вызывающийкод. Поэтому когда функция изменяет его элементы, изменения остаются в массиве в main:
#include <stdio.h>
void add_to_all(int numbers[], int count, int amount) {
for (int i = 0; i < count; i++) {
numbers[i] += amount;
}
}
int main(void) {
int points[] = {5, 8, 7};
add_to_all(points, 3, 10);
for (int i = 0; i < 3; i++) {
printf("%d\n", points[i]);
}
return 0;
}Эта программа выводит:
15
18
17Функция прибавила 10 к каждому элементу массива points в main. Почему массивыведут себя так, вы узнаете в уроке об указателях. Пока запомните: функция может изменять элементы массива,который вы ей передали.
Задание
- 1
Программа не компилируется, потому что функции
averageещё нет (прочитайте первуюошибку). Напишите её на месте комментария: у неё два параметра, массивnumbersтипаintи его количествоcountтипаint, а возвращает она среднее значениеэлементов какdouble: их сумму, делённую наcount. Остерегайтесь целочисленногоделения: храните сумму в переменной типаdouble. Тогда программа выведет средние температурыдвух недель,20.80и12.75. - 2
В первую неделю термометр показывал каждую температуру на 1 градус ниже настоящей. Под
averageнапишите функциюadd_to_allс тремя параметрами: массивомnumbersтипаint, его количествомcountи числомamount(оба типаint).Она прибавляетamountк каждому элементу массива и ничего не возвращает. В концеmain,передreturn 0;, вызовитеadd_to_all(week1, 5, 1), а затем снова выведите среднеезначениеweek1так же, как выше. Программа выведет21.80: функция изменила массив вmain.