Многие программисты предпочитают думать о функции как о “черном ящике”, определенном в терминах информации, которая в него поступает (его ввод), и значения или действия, которое он производит (его вывод). Вас не заботит то, что происходит внутри черного ящика, если только вы сами не занимаетесь разработкой этой функции. Например, когда вы используете функцию printf(), то знаете, что должны передать ей управляющую строку и возможно некоторые аргументы. Вам также известен вывод, который функция printf() должна сгенерировать. Однако вы вовсе не задумываетесь о коде, реализующем printf(). Такой подход в отношении функций позволяет сосредоточиться на общей структуре программы, не отвлекаясь на детали. До того, как приступать к написанию кода, тщательно обдумайте, что должна делать функция и какова ее роль в программе.
Что вы должны знать о функциях? Необходимо знать, как их правильно определять, вызывать и обеспечивать взаимодействие между ними. Чтобы освежить эти моменты в памяти, мы начнем с рассмотрения очень простого примера, а затем будем добавлять в него новые возможности, пока не будет получена полная картина.
Создание и использование простой функции
Нашей первой скромной целью является создание функции, которая выводит 40 звездочек в строке. Чтобы придать этой функции смысл, мы включим ее в программу, которая выводит простой заголовок письма. Полный код программы приведен в листинге 9.1. Она состоит из функций main() и starbar().
Листинг 9.1 .Программа lethead2. с

328 глава 9
Вывод программы выглядит следующим образом:
************★★★★**★★★★★★★★★★★★★★*★★★★★★★
GIGATHINK, INC.
101 Megabuck Plaza
Megapolis, CA 94904
****************************************
Анализ программы
Ниже отмечены некоторые важные аспекты этой программы.
• Идентификатор starbar применяется в трех отдельных контекстах: в прототипе функции, который сообщает компилятору разновидность функции starbar(), в вызове функции, который приводит к выполнению функции, и в определении функции, где в точности указано все, что делает функция.
• Подобно переменным, функции имеют типы. В любой программе, в которой используется функция, предварительно должен быть объявлен тип этой функции. Поэтому данный прототип ANSI С предшествует объявлению функции main(): void starbar(void);
Круглые скобки указывают, что starbar является именем функции. Первое ключевое слово void — это тип функции; тип void говорит о том, что функция не возвращает значения. Второе слово void (в круглых скобках) означает, что функция не принимает аргументов. Точка с запятой указывает на то, что функция объявляется, а не определяется. То есть эта строка сообщает о том, что в программе применяется функция starbar(), что эта функция не возвращает значения и не принимает аргументов и что компилятор должен искать ее определение где-то в другом месте. Для компиляторов, не распознающих прототипы ANSI С, просто объявите тип так:
void starbar();
Следует отметить, что некоторые очень старые компиляторы не распознают тип void. В этом случае для функций, которые не возвращают значения, используйте тип int. И постарайтесь подыскать более новый компилятор.
• В общем случае прототип указывает как тин возвращаемого функцией значения, так и типы ожидаемых ею аргументов. Обобщенно эту информацию называют сигнатурой функции. В данном конкретном случае сигнатура указывает, что функция не имеет ни возвращаемого значения, ни аргументов.
• Прототип функции starbar() размещен в программе перед функцией main(); вместо этого его можно было бы поместить внутрь функции main() там, где находятся объявления переменных. Допустим любой из этих способов.
• Программа вызывает функцию (обращается к функции) starbar() из функции main(), для чего указывается ее имя, круглые скобки и точка с запятой, таким образом создавая оператор:
starbar();
Это форма вызова функции типа void. Каждый раз, когда управление сталкивается с оператором starbar();, оно ищет функцию starbar() и выполняет содержащиеся в ней инструкции. По завершении выполнения кода starbar() управление возвращается на следующую строку в вызывающей функции — в данном случае main() (рис. 9.1). (Точнее говоря, компилятор преобразует программу на языке С в код на машинном языке, который ведет себя описанным образом.)
Функции 329

Читать дальше