Чтение онлайн

на главную

Жанры

Программирование. Принципы и практика использования C++ Исправленное издание
Шрифт:

В стандартной библиотеке предусмотрено множество полезных функций, таких как функция для вычисления корня квадратного из числа

sqrt
, использованная в разделе 3.4. Однако многие функции мы пишем самостоятельно. Рассмотрим возможное определение функции
square
.

int square(int x) // возвращает квадрат числа x

{

return x*x;

}

Первая строка этого определения утверждает, что это функция (об этом говорят скобки), которая называется

square
, принимающая аргумент типа
int
(с именем) и возвращающая значение типа
int
(тип результата
всегда предшествует объявлению функции); иначе говоря, ее можно использовать примерно так:

int main

{

cout << square(2) << '\n'; // выводим 4

cout << square(10) << '\n'; // выводим 100

}

Мы не обязаны использовать значение, возвращаемое функцией, но обязаны передать функции именно столько аргументов, сколько предусмотрено. Рассмотрим пример.

square(2); // возвращаемое значение не используется

int v1 = square; // ошибка: пропущен аргумент

int v2 = square; // ошибка: пропущены скобки

int v3 = square(1,2); // ошибка: слишком много аргументов

int v4 = square("two"); // ошибка: неверный тип аргумента —

// ожидается int

Многие компиляторы предупреждают о неиспользуемых возвращаемых значениях, как показано выше. По этой причине может показаться, будто компилятор способен понять, что, написав строку "
two
", вы на самом деле имели в виду число
2
. Однако компилятор языка С++ совсем не так умен. Компьютер просто проверяет, соответствуют ли ваши инструкции синтаксическим правилам языка С++, и точно их выполняет. Если компилятор станет угадывать, что вы имели в виду, то он может ошибиться и вы — или пользователи вашей программы — будете огорчены. Достаточно сложно предсказать, что будет делать ваша программа, если компилятор будет пытаться угадывать ваши намерения.

Тело функции является блоком (см. раздел 4.4.2.2), который выполняет реальную работу.

{

return x*x; // возвращаем квадрат числа x

}

Для функции

square
эта работа тривиальна: мы вычисляем квадрат аргумента и возвращаем его в качестве результата. Выразить это на языке С++ проще, чем на естественном языке. Это типично для простых идей. Помимо всего прочего, язык программирования предназначен именно для простого и точного выражения таких простых идей.

Синтаксис определения функции можно описать так:

тип идентификатора (список параметров) тело функции

За типом (возвращаемого значения) следует идентификатор (имя функции), за ним — список параметров в скобках, затем — тело функции (исполняемые инструкции). Список аргументов, ожидаемых функцией, называют списком параметров, а элементы этого списка — параметрами (или формальными аргументами).

Список параметров может быть пустым. Если не хотите возвращать результат, то перед именем функции в качестве типа возвращаемого значения следует поставить ключевое слово

void
(означающее “ничего”). Рассмотрим пример.

void write_sorry // не принимает никаких аргументов;

// ничего не возвращает

{

cout << "Извините \n";

}

Специфические аспекты, связанные с языком программирования, будут описаны в главе 8.

4.5.1. Зачем нужны функции

Функции нужны в ситуациях, когда требуется выделить некие вычисления и присвоить им конкретное имя, руководствуясь следующими соображениями.

• Эти вычисления логически отделены от других.

• Отделение вычислений делает программу яснее (с помощью присваивания имен функциям).

• Функцию можно использовать в разных местах программы.

• Использование функций упрощает отладку программы.

В дальнейшем мы увидим много примеров, в которых следует руководствоваться этими соображениями. Обратите внимание на то, что в реальных программах используются тысячи функций и даже несколько сотен тысяч функций. Очевидно, что мы никогда не сможем понять такие программы, если их части (т.е. фрагменты вычислений) не будут отделены друг от друга и не получат имен. Кроме того, как мы вскоре убедимся, многие функции часто оказываются полезными в разных ситуациях, и повторять один и тот же код каждый раз довольно утомительно. Например, вы, конечно, можете писать выражения вида

x*x
, или
7*7
, или
(x+7)*(x+7)
, а не
square(x)
,
square(7)
или
square(x+7)
. Однако функция square сильно упрощает такие вычисления. Рассмотрим теперь извлечение квадратного корня (в языке С++ эта функция называется
sqrt
): можете написать выражение
sqrt(x)
, или
sqrt(7)
, или
sqrt(x+7)
, а не повторять код, вычисляющий квадратный корень, запутывая программу. И еще один аргумент: можете даже не интересоваться, как именно вычисляется квадратный корень числа в функции
sqrt(x)
, — достаточно просто передать функции аргумент
x
.

В разделе 8.5 мы рассмотрим множество технических деталей, связанных с функциями, а пока рассмотрим еще один пример. Если мы хотим действительно упростить цикл в функции

main
, то можно было бы написать такой код:

void print_square(int v)

{

cout << v << '\t' << v*v << '\n';

}

int main

{

for (int i = 0; i<100; ++i) print_square(i);

}

Почему же мы не использовали версию программы на основе функции

print_square
? Дело в том, что эта программа ненамного проще, чем версия, основанная на функции
square
, и, кроме того,

• функция

print_square
является слишком специализированной и вряд ли будет использована в другой программе, в то время как функция
square
, скорее всего, будет полезной для других пользователей;

• функция

square
не требует подробной документации, а функция
print_square
очевидно требует пояснений.

Функция

print_square
выполняет два логически отдельных действия:

• печатает числа;

• вычисляет квадраты.

Программы легче писать и понимать, если каждая функция выполняет отдельное логическое действие. По этой причине функция

square
является более предпочтительной.

В заключение попробуем ответить, почему мы использовали функцию

square(i)
, а не выражение
i*i
, использованное в первой версии программы? Одной из целей функций является упрощение кода путем распределения сложных вычислений по именованным функциям, а для программы 1949 года еще не было аппаратного обеспечения, которое могло бы непосредственно выполнить операцию “умножить”. По этой причине в первоначальной версии этой программы выражение
i*i
представляло собой действительно сложное вычисление, как если бы вы выполняли его на бумаге. Кроме того, автор исходной версии, Дэвид Уилер, ввел понятие функций (впоследствии названных процедурами) в современном программировании, поэтому было вполне естественно, что он использовал их в своей программе.

Поделиться:
Популярные книги

Назад в СССР: 1986 Книга 5

Гаусс Максим
5. Спасти ЧАЭС
Фантастика:
попаданцы
альтернативная история
5.75
рейтинг книги
Назад в СССР: 1986 Книга 5

Неудержимый. Книга III

Боярский Андрей
3. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Неудержимый. Книга III

Мастер 3

Чащин Валерий
3. Мастер
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Мастер 3

Конструктор

Семин Никита
1. Переломный век
Фантастика:
попаданцы
альтернативная история
4.50
рейтинг книги
Конструктор

Наследник Четырех

Вяч Павел
5. Игра топа
Фантастика:
героическая фантастика
рпг
6.75
рейтинг книги
Наследник Четырех

Чехов. Книга 2

Гоблин (MeXXanik)
2. Адвокат Чехов
Фантастика:
фэнтези
альтернативная история
аниме
5.00
рейтинг книги
Чехов. Книга 2

Легат

Прокофьев Роман Юрьевич
6. Стеллар
Фантастика:
боевая фантастика
рпг
6.73
рейтинг книги
Легат

Земная жена на экспорт

Шах Ольга
Любовные романы:
любовно-фантастические романы
5.57
рейтинг книги
Земная жена на экспорт

Идеальный мир для Лекаря 11

Сапфир Олег
11. Лекарь
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 11

Столичный доктор. Том II

Вязовский Алексей
2. Столичный доктор
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Столичный доктор. Том II

Столичный доктор. Том III

Вязовский Алексей
3. Столичный доктор
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Столичный доктор. Том III

Пропала, или Как влюбить в себя жену

Юнина Наталья
2. Исцели меня
Любовные романы:
современные любовные романы
6.70
рейтинг книги
Пропала, или Как влюбить в себя жену

Нефилим

Демиров Леонид
4. Мания крафта
Фантастика:
фэнтези
боевая фантастика
рпг
7.64
рейтинг книги
Нефилим

Бывший муж

Рузанова Ольга
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Бывший муж