Описание функции
Функция описывается заголовком и телом.
Заголовок содержит:
- класс памяти;
- имя функции;
- тип возвращаемого результата;
- имена и типы формальных параметров, заключенные в ( ) и разделенные запятыми.
Телом функции является составной оператор, объединяющий описание внутренних переменных функции и операторы, реализующие функцию[1]:
[][] ([]
{
Тело функции
}
В теле функции м.б. оператор return, м. не б. оператор return, м.б. более одного return.
Если— void, то return не нужен.
Класс памяти может отсутствовать (устанавливается по умолчанию).
Список формальных параметров может быть void (отсутствие параметров). В таком случае скобки после идентификатора функции все же требуются, хотя они и пусты.
Спецификатор класса памяти в определении функции определяет функцию как static или extern. Функция с классом памяти static видима только в том исходном файле, в котором она определена. Все другие функции с классом памяти extern, заданным явно или неявно, видимы во всех исходных файлах, которые образуют программу.
Если спецификатор класса памяти опускается в определении функции, то подразумевается класс памяти extern. Спецификатор класса памяти extern может быть явно задан в определении функции, но этого не требуется.
Спецификатор класса памяти требуется при определении функции только в одном случае, когда функция объявляется где-нибудь в другом месте в том же самом исходном файле с спецификатором класса памяти static. Спецификатор класса памяти static может быть также использован, когда определяемая функция предварительно объявлена в том же самом исходном файле без спецификатора класса памяти. Как правило, функция, объявленная без спецификатора класса памяти, подразумевает класс extern. Однако, если определение функции явно специфицирует класс static, то функции дается класс static.
Описание функции может следовать за функцией main() или находиться вообще в другом месте (файле или библиотеке).
Для реализации процедур общего вида в Си используется функции, не возвращающие значение. В поле определения типа результата таких функций рекомендуется писать ключевое слово void, указывающее, что функция не возвращает значение.
Функции могут возвращать величины любого типа за исключением массивов и функций. Тип возврата функции определяет размер и тип возвращаемого значения.
Функции не могут возвращать массивов или функций, но они могут возвращать указатели на любой тип, включая массивы и функции. Тип возврата, задаваемый в определении функции, должен соответствовать типам возвратов, заданных в объявлениях этой функции, сделанных где-то в программе. Функции с типом возврата int могут не объявляться перед вызовом.
Тип значения возврата функции используется только тогда, когда функция возвращает значение, которое вырабатывается, если выполняется оператор return, содержащий выражение. Выражение ВЫЧИСЛЯЕТСЯ, ПРЕОБРАЗУЕТСЯ к типу возврата, если это необходимо, и ВОЗВРАЩАЕТСЯ в точку вызова. Если оператор return не выполняется или если выполняемый оператор return не содержит выражения, то значение возврата функции НЕ ОПРЕДЕЛЕНО. Если в этом случае вызывающая функция ожидает значение возврата, то поведение программы также не определено.
Пример 1 :
/* функция для вычисления по формуле */
double linefunc (double x, double a, double b)
{
return (a*x + b);
}
Пример 2 :
/* функция возвращает степень n0 числа х */
long int pow (int x, int n)
{
int i;
long int p;
p = 1;
for (i = 1; i
p = p * x;
return p;
}
void main ()
{
int i;
for (i = 0; i10; i++)
cout
}
Формальные параметры — это переменные, которые принимают значения, переданные функции от функционального вызова. Формальные параметры объявляются в списке параметров в начале описания функции. Список параметров определяет имена параметров и порядок, в котором они принимают значения при вызове функции.
Формальные параметры – входные и выходные. Входные – те, которые должны быть известны для вычислений в функции. Выходные – результаты.
Список параметров состоит из нуля или более идентификаторов, разделенных запятой. Список должен быть ограничен круглыми скобками даже в случае, когда он пуст.
Объявления параметров определяют ТИП и РАЗМЕР величин, запоминаемых в формальных параметрах. Эти объявления имеют тот же самый синтаксис, как и другие объявления. Формальные параметры могут быть основного, структурного, совмещающего, адресного типов или типа массив.
Параметры могут иметь только классы памяти auto и register. Если класс памяти не задан, то подразумевается класс памяти auto. Формальные параметры могут быть объявлены в любом порядке.
Идентификаторы формальных параметров используются в теле функции в качестве ссылок на величины, передаваемые функции. Эти идентификаторы НЕ МОГУТ БЫТЬ использованы для переменных, объявляемых внутри тела функции.
Тело функции — это просто СОСТАВНОЙ оператор. Составной оператор содержит операторы, которые определяют действия функции, и может также содержать объявления переменных, используемых в этих операторах. Все переменные, объявленные в теле функции, имеют тип памяти auto, если они не объявлены иначе. Когда вызывается функция, то создается память для локальных переменных и производится их инициализация (если она задана). Управление передается первому оператору из списка составного оператора и начинается процесс выполнения, который продолжается до тех пор, пока не встретится оператор return или конец тела функции. Управление при этом возвращается в точку вызова.
Если функция возвращает значение, то должен быть выполнен оператор return, содержащий выражение. Значение возврата НЕ ОПРЕДЕЛЕНО, если не выполнен оператор return или, если в оператор return не было включено выражение.
Пример 3 :
/* Пояснения к различным описаниям функций*/
static add (int x, int y){return (x+y);} | По умолчанию тип возврата функции add определен как int. Функция имеет класс памяти static. Это означает, что фнкция может быть вызвана только функциями того же самого исходного файла. |
typedef struct{char name [20];int id;long class;} STUDENT; STUDENT sortstu (STUDENT a, STUDENT b){return ((a.id | Возвращается тип STUDENT Посредством объявления typedef определен структурный тип STUDENT. Далее определена функция sortstu с типом возврата STUDENT. Функция выбирает и возвращает один из двух структурных аргументов. |
char *smallstr (char s1[ ], char s2[ ]){int i;i = 0;while (s1[i]!=’\0’s2[i]!=’\0′)i++;if (s1[i]==’\0»)return (s1);elsereturn (s2);} | Определена функция, возвращающая указатель на массив символов. Функция принимает в качестве аргументов два символьных массива (строки) и возвращает указатель на более короткую строку. Указатель на массив адресует элементы типа char. Таким образом, тип возврата функции будет указателем на char. |
struct student{char name [20];int id;long class;}; match (struct student * r, char *n){int i=0;while (r-name [i] == n[i])if (r-name [i++] == ‘\0’)return (r-id);return (0);} | Функция match объявлена с двумя аргументами. Первый аргумент — это указатель на структуру типа student, второй указатель на объект типа char.Заметим, что имя массива, заданное в качестве второго аргумента в вызове функции преобразуется к указателю на char. Соответствующий формальный параметр также объявлен как указатель на char и используется в выражении как идентификатор массива. Так как идентификатор массива рассматривается как адресное выражение, то результат объявления формального параметра как char *n будет тем же самым, что и char n [].Внутри функции локальная переменная i определяется и используется в качестве индекса массива. Функция возвращает структурный элемент id, если элемент структуры name сравнился с массивом n, в противном случае функция возвращает нуль. |
Объявление функции
Введение в программу прототипов функций преследует несколько целей. Во-первых, это позволяет использовать в данном модуле функцию, описанную в каком-нибудь другом модуле. Тогда из прототипа компилятор получает сведения, сколько параметров, какого типа и в какой последовательности получает данная функция. Во-вторых, если в начале модуля вы определили прототипы функций, то последовательность размещения в модуле описания функций безразлична. При отсутствии прототипов любая используемая функция должна быть описана ДО ЕЕ ПЕРВОГО ВЫЗОВА в тексте. Это прибавляет хлопот, а иногда при взаимных вызовах функций друг из друга вообще невозможно. И, наконец, прототипы, размещенные в одном месте (обычно в начале модуля), делают программу более наглядной и самодокументированной. Особенно в случае, если вы снабжаете прототипы, хотя бы краткими комментариями.
Прототип функции имеет такой же формат, что и определение функции с такой лишь разницей, что он не имеет тела функции и что заголовок функции кончается знаком “;”.
Прототип функции задает имя функции, типы и число формальных параметров, тип возвращаемого значения и класс памяти. Формальные параметры могут иметь имена, но эти имена компилятор не использует:
double linefunc ();
double linefunc (double, double, double);
double linefunc (double x, double a, double b);
Компилятор использует прототип функции для сравнения типов фактических параметров в виде функции c типами формальных параметров.
Если объявление функции не задано, то по умолчанию строится прототип на основании информации, взятой из первой ссылки на функцию. Однако такой прототип может неадекватно представлять последующий вызов или определение функции. Поэтому рекомендуется ВСЕГДА ЗАДАВАТЬ ПРОТОТИПЫ функций.
Для того чтобы объявить функцию, не имеющую аргументов, может быть использовано специальное ключевое слово void на месте списка типов аргументов. Компилятор вырабатывает предупреждающее сообщение, если в вызове такой функции будут специфицированы аргументы. Еще одна специальная конструкция допускается в списке типов аргументов. Это фраза void *, которая специфицирует аргумент типа указатель. Эта фраза может быть использована в списке типов аргументов вместо имени типа.
Примеры объявления функций
int add(int, int); | оъявляется функция, поименованная add, которая требует два аргумента типа int и возвращает величину типа int. |
double calc( ); | объявляется функция, поименованная calc, которая возвращает величину типа double. Список типов аргументов не задан. |
char *strfind(char *,…); | объявляется функция, поименованная strfind, которая возвращает указатель на величину типа char. Функция требует, по крайней мере один аргумент — указатель на величину типа char. Список типов аргументов заканчивается запятой с многоточием, обозначающим, что функция может потребовать большее число аргументов. |
void draf(void); | объявляется функция с типом возврата void (нет возвращаемой величины). Список типов аргументов также void, означающий отсутствие аргументов для этой функции. |
double (*sum(double, double)) [3]; | sum объявляется как функция, возвращающая указатель на массив из трех величин типа double. Функция sum требует два аргумента, каждый из которых является величиной типа double. |
int (*select(void)) (int) ; | функция, поименованная select, объявлена без аргументов и возвращает указатель на функцию. Указатель возврата ссылается на функцию, требующую один аргумент типа int и возвращающую величину типа int. |
char *p;short *q;int prt(void *); | объявлена функция prt, которая требует аргумент — указатель любого типа, и которая возвращает величину типа int. Любой указатель p или q могли бы быть использованы как аргументы функции без выдачи при этом предупреждающего сообщения. |
Вызов функций
Вызов функции — это выражение, которое передает управление и ФАКТИЧЕСКИЕ параметры (если они есть) функции. Вызов функции связан с выполнением действий над фактическими параметрами, заданных в ее определении.
Вызов функции имеет следующее синтаксическое представление:
O если тип возврата void:
([]);
O // если тип возврата не void
=([]);
Фактические параметры должны «встать на место» формальных параметров при вызове функции. Фактические аргументы могут быть любой величиной основного, структурного, совмещающего или адресного типов.
int add (int x, int y){return (x+y);} | void main( ){int a = 2;int b = 3;cout | Формальные параметры – x и y.Фактические параметры – выражения 5*a и 4*b. |
Несоответствие типов формальных и фактических параметров может произвести серию ошибок, особенно когда несоответствие влечет за собой отличия в размерах массивов.
Выполнение вызова функции:
1) вычисляются выражения входящие в список выражений в фактических параметров; сравниваются типы результатов вычисленных выражений с типом соответствующим формальным параметрам, и если нет совпадения, то производится преобразование типов (проверяется столько аргументов, сколько задано). Если вместо списка формальных параметров — void, то в прототипе тоже void, при обращении не должно быть никаких параметров, то есть пишутся только скобки ().
2) передаются фактические параметры в область памяти формальных;
3) передается управление на первый оператор тела процедуры;
4) производится вычисление и возврат по оператору return; если его нет, то вычисления производятся до последнего оператора и возвращаемое значение не определено.
Передача параметров
В Си все аргументы передаются ПО ЗНАЧЕНИЮ.
При передаче параметра по значению аргументом может быть произвольное выражение, значение которого передается в подпрограмму.
Статьи к прочтению:
Функции c++ примеры. Синтаксис. Объявление, реализация функции. Параметры, аргументы.C++ #33
Похожие статьи:
-
Объявление (или описание) функции в программе.
Вопрос Вопрос Пример: Если или Вопрос mkdir команда для создания новых каталогов$ mkdir имя_каталогаилиmkdir имя_каталога1 имя_каталога2 имя_каталога3…
-
Массив Массив (или массив данных) – это набор однородных(одного типа) элементов, к которым можно обратиться по их порядковому номеру (индексу). Массив…