Вы, вероятно, обратили внимание на инструкцию
Объявление
int power(int m, int n);
стоящее непосредственно перед
Имена параметров не требуют согласования. Фактически в прототипе они могут быть произвольными или вообще отсутствовать, т. е. прототип можно было бы записать и так:
int power(int, int);
Однако удачно подобранные имена поясняют программу, и мы будем часто этим пользоваться.
Историческая справка. Самые большие отличия ANSI-Си от более ранних версий языка как раз и заключаются в способах объявления и определения функций. В первой версии Си функцию power требовалось задавать в следующем виде:
/* power: возводит base в n-ю степень, n ›= 0 */
/* (версия в старом стиле языка Си) */
power(base, n)
int base, n;
{
int i, р;
p = 1;
for (i = 1; i ‹= n; ++i)
р = р * base;
return р;
}
Здесь имена параметров перечислены в круглых скобках, а их типы заданы перед первой открывающей фигурной скобкой. В случае отсутствия указания о типе параметра, считается, что он имеет тип
Описание power в начале программы согласно первой версии Си должно было бы выглядеть следующим образом:
int power();
Нельзя было задавать список параметров, и поэтому компилятор не имел возможности проверить правильность обращений к power. Так как при отсутствии объявления power предполагалось, что функция возвращает значение типа int, то в данном случае объявление целиком можно было бы опустить.
Новый синтаксис для прототипов функций облегчает компилятору обнаружение ошибок в количестве аргументов и их типах. Старый синтаксис объявления и определения функции все еще допускается стандартом ANSI, по крайней мере на переходный период, но если ваш компилятор поддерживает новый синтаксис, мы настоятельно рекомендуем пользоваться только им.
Упражнение 1.15. Перепишите программу преобразования температур, выделив само преобразование в отдельную функцию.
1.8 Аргументы. Вызов по значению
Одно свойство функций в Си, вероятно, будет в новинку для программистов, которые уже пользовались другими языками, в частности Фортраном. В Си все аргументы функции передаются "по значению". Это следует понимать так, что вызываемой функции посылаются значения ее аргументов во временных переменных, а не сами аргументы. Такой способ передачи аргументов несколько отличается от "вызова по ссылке" в Фортране и спецификации var при параметре в Паскале, которые позволяют подпрограмме иметь доступ к самим аргументам, а не к их локальным копиям.
Главное отличие заключается в том, что в Си вызываемая функция не может непосредственно изменить переменную вызывающей функции: она может изменить только ее частную, временную копию.
Однако вызов по значению следует отнести к достоинствам языка, а не к его недостаткам. Благодаря этому свойству обычно удается написать более компактную программу, содержащую меньшее число посторонних переменных, поскольку параметры можно рассматривать как должным образом инициализированные локальные переменные вызванной подпрограммы. В качестве примера приведем еще одну версию функции power, в которой как раз использовано это свойство.
/* power: возводит base в n-ю степень; n ›= 0, версия 2 */
int power(int base, int n)
{
int p;
for (p = 1; n › 0; -n)
p = p * base;
return p;
}
Параметр n выступает здесь в роли временной переменной, в которой циклом