Шрифт:
Имена переменных в круглых скобках приводить необязательно, но полезно для лучшего документирования. Обратите внимание на обязательное использование точки с запятой в конце записи прототипа. Приведем три примера прототипов функций:
В примере 1 функция compute использует два аргумента. Аргументы функции — это те переменные, которые необходимы для ее корректного исполнения. Спецификация типа аргументов функции приведена в круглых скобках. В данном случае указано, что функция compute будет использовать два целочисленных аргумента, т.е. при вызове функции ей должны быть указаны для целочисленных значения. Результатом действия функции compute будет вычисление значения некоторой переменной. Спецификация типа возвращаемой переменной приведена перед именем функции. В данном случае это тоже целочисленный 16 разрядный формат.
В примере 2 записан прототип функции change. Эта функция предполагает наличие трех аргументов: однобайтового целочисленного name, числа с именем number в формате с плавающей запятой и двухбайтового целого числа с именем a. Функция change должна возвратить значение переменной в формате с плавающей запятой. В примере 3 объявляется функция find с тремя аргументами, для которых указан тип данных, но не указаны имена.
При знакомстве с программами на Си Вы можете встретить прототип функции, в котором на первом месте указано слово extern:
Подобная запись означает, что определение функции not_here не включено в текст данного программного модуля (текущего файла), а располагается во внешнем модуле (другом файле), который будут объединен с текущим модулем при составлении конечного исполняемого кода программы.
Если функция была объявлена в тексте какого либо программного модуля, то она должна быть определена в этом же модуле или другом модуле, например в файле библиотеки. Мы обсудим правила определения функции в следующем параграфе, а пока приведем примеры вызова каждой из трех объявленных функций:
Обратите внимание, спецификация типа возвращаемой переменной в записи вызова функции исчезла, а в поле аргументов появились записи их численных значений.
3.4.4. Описание функций
Каждая объявленная в начале некоторого программного модуля функция должна быть определена в этом модуле или в тексте программы другого модуля, который в процессе генерации исполняемого кода программы будет присоединен к текущему модулю. Функция может быть также определена в подключаемом файле стандартной библиотеки. Текст определения функции может быть записан в любом месте программного модуля, однако принято определения всех используемых функций располагать сразу за текстом основной программы main.c. Например, предположим, что объявленная в предыдущем параграфе функция compute вычисляет модуль вектора двух ортогональных составляющих a и b и возвращает его в переменной с именем result. Прототип функции:
Определение функции начинается с комментария, в котором перечисляются производимые функцией действия. Далее следует повтор строки прототипа функции, но без заключительных точки с запятой. Ниже последовательно располагаются все операторы функции, которые сверху и снизу заключаются в фигурные скобки.
В приведенном примере строка 1 открывает определение функции, информируя компилятор о том, что имя функции compute, она использует для своей работы две целочисленных переменных и возвращает одну целочисленную переменную. Фигурная скобка в строке 2 открывает область операторов определяемой функции. В строке 3 объявляются локальные переменные, т.е. те переменные, которые используются только внутри функции. Это переменные sum и result. Операторы, расположенные в строках 4 и 5 выполняют заявленные в описании функции вычисления. Причем в строке 5 используется функция извлечения квадратного корня sqrt, которая определена в библиотеке математических вычислений. При компиляции эта библиотека должна быть обязательно присоединена к файлу с рассматриваемой функцией посредством специальных директив компилятора, которые мы рассмотрим в следующем параграфе. В строке 5 следует обратить внимание на оператор (int) перед вызовом функции извлечения квадратного корня. Этот оператор осуществляет преобразование типа данных к заявленному в прототипе функции compute целочисленному формату int, поскольку функция извлечения квадратного корня возвращает данные в другом формате. В строке 6 применен оператор возврата return, которые позволяет использовать значение переменной result другими операторами основной программы. Фигурная скобка в строке 7 завершает определение функции. Любые операторы, записанные после скобки, уже не будут ассоциироваться с функцией compute.
На основании анализа примера Вам следует запомнить, что каждая функция должна быть определена в строго заданном формате исходного текста программы. Сначала следует строка прототипа функции, в которой указывается имя функции, используемые переменные и возвращаемые переменные. В отличие от строки объявления функции, точка с запятой в конце строки прототипа при определении функции не ставятся. Затем следуют операторы функции, заключенные в фигурные скобки. Если в поле возвращаемой переменной прототипа указан ее тип, то последним оператором функции должен быть оператор return. Если же в поле возвращаемой переменной прототипа стоит служебное слово void, то функция не возвращает данных. Назначение такой функции — выполнить определенный набор действий по управлению периферийными модулями МК или внешними устройствами. Соответственно и оператор return в последней строке отсутствует.