Вход/Регистрация
Программирование. Принципы и практика использования C++ Исправленное издание
вернуться

Страуструп Бьерн

Шрифт:

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
представляло собой действительно сложное вычисление, как если бы вы выполняли его на бумаге. Кроме того, автор исходной версии, Дэвид Уилер, ввел понятие функций (впоследствии названных процедурами) в современном программировании, поэтому было вполне естественно, что он использовал их в своей программе.

  • Читать дальше
  • 1
  • ...
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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