Области действия функцийОпределения и объявления
До сих пор мы ничего не говорили ни о взаимном расположении в программе определения функции и ее вызова, ни о соответствии формальных и фактических параметров, ни о контроле такого соответствия. Конечно, нельзя считать, что транслятор "знает" о всех функциях, когда либо написанных, либо находящихся в библиотеках, текстовых файлах и т.д.. Каждая программа должна сама сообщать транслятору необходимую информацию о функциях, которые она собирается вызывать. Перечислим, какую именно:
-имя функции;
-тип результата;
-список формальных параметров (переменные и типы). При ее наличии транслятор может корректно сформировать вызов функции, даже если текст ее (определение) отсутствует в программе.
Вся перечисленная информация о функции находится в ее заголовке. Таким образом, достаточно этот заголовок привести отдельно, и проблема корректного вызова решается. Такой заголовок называется объявлением или в рассматриваемом нами варианте синтаксиса ПРОТОТИПОМ ФУНКЦИИ.
Теперь перечислим причины такого "незнания" транслятора. Во-первых, трансляторы обычно используют довольно простые алгоритмы просмотра текста программы, "не заглядывая" вперед. Поэтому обычно на данный момент трансляции содержание текста программы за текущим транслируемым оператором ему неизвестно. Во-вторых, функция может быть в библиотеке. В третьих -в другом текстовом файле, содержащем часть Си-программы. Во всех этих случаях необходимо использовать объявления. Единственный случай, когда этого делать не надо -когда определение функции присутствует ранее по тексту программы:
int B[10];
int sum(int s[],int n); // Объявление функции,
// определенной далее по тексту
extern int printf(char *,...);
// Объявление библиотечной функции
// с переменным числом параметров
extern int other(void); // Объявление функции без
// параметров из другого
void main() // файла программы
{ //
sum(B,10); // Вызовы объявленных функций
cout << B[i]);
other();
}
int sum(int s[], int n)
{...}
Из примера видно, что объявление функции практически дублирует заголовок, отличаясь в некоторых деталях:
-объявление заканчивается символом ";" ;
-если функция находится вне текущего файла, то объявление предваряется служебным словом extern;
-имена переменных в списке формальных параметров объявления могут отсутствовать;
-если функция не имеет формальных параметров, то в объявлении присутствует формальный параметр типа void.
Имея предварительно определенную функцию или ее объявление, транслятор в состоянии проверить соответствие формальных и фактических параметров функции как по их количеству, так и по типам. При этом транслятор может выполнить неявные преобразования типов фактических параметров к типам формальных, если это потребуется:
extern double sin(double);
int x;
double y;
y = sin(x);
//------Неявное преобразование (double)x
В заключение отметим существенную разницу между определением и объявлением.
ОПРЕДЕЛЕНИЕ ОБЪЕКТА (переменной, функции) задает объект и приводит к трансляции во внутреннее представление. ОБЪЯВЛЕНИЕ ОБЪЕКТА -- это информация транслятору о факте наличия объекта в недоступной на данный момент части программы.
В дальнейшем при более серьезном обсуждении принципов модульного программирования будет рассмотрен ряд вопросов, касающихся этого материала:
-определения и объявления функций и переменных;
-исторические варианты синтаксиса определений и объявлений и контроля параметров функций;
-ошибки программирования, связанные с объявлениями.