Язык программирования Си для персонального компьютера
Шрифт:
<тело функции>
Спецификация класса памяти <спецификация КП> задает класс памяти функции. <Спецификация типа> в совокупности с описателем определяет тип возвращаемого значения и имя функции. <Список объявлений параметров> аналогичен списку типов аргументов в прототипе функции (см. раздел 3.5 "Объявление функции"). Он содержит объявления формальных параметров через запятую. Однако если в прототипе область действия идентификаторов ограничена этим же прототипом, то в списке объявлений параметров идентификаторы именуют
В следующих разделах детально описываются перечисленные элементы определения функции.
Класс памяти
В определении функции допускается указание спецификации класса памяти static или extern. Классы памяти функций рассматривались в разделе 3.6.
Модификаторы типа функции
Компилятор языка Си поддерживает ряд модификаторов типа функций: pascal, cdecl, interrupt, near, far и huge (модификатор interrupt не реализован в версии 4 СП MSC). Модификаторы рассмотрены в разделе 3.3.3 "Описатели с модификаторами".
Типы возвращаемых значений
Синтаксис задания типа возвращаемого значения функции описан в разделе 3.5 "Объявление функции", функция может возвращать значение любого типа, кроме массива или функции; она может, в частности, возвращать указатель на любой тип, включая массив и функцию.
Тип возвращаемого значения, задаваемый в определении функции, должен соответствовать типу возвращаемого значения во всех объявлениях этой функции, если они имеются в программе. Для вызова функции с типом возвращаемого значения int не требуется ее предварительно объявлять или определять. Функции с другими типами возвращаемого значения должны быть определены или объявлены до того, как они будут вызваны.
Возвращаемое значение функции вырабатывается при выполнении оператора возврата return, содержащего выражение. Выражение вычисляется, преобразуется к типу возвращаемого значения и возвращается в точку вызова функции. Если оператор return отсутствует или не содержит выражения, то возвращаемое значение функции не определено. Если в этом случае вызывающая функция ожидает возвращаемое значение, то поведение программы непредсказуемо.
Примеры:
/* пример 1 */
/* тип возвращаемого значения int */
static add(int х, int у)
{
return (х + у);
}
/* пример 2 */
/* тип возвращаемого значения STUDENT */
typedef struct {
char name [20],
int id;
long class;
} STUDENT;
STUDENT sortstu(STUDENT a, STUDENT b)
{
return (a.id < b.id ? a : b);
}
/* пример 3 */
/* тип возвращаемого значения — указатель на char */
char *smallstr(char *s1, char *s2)
{
int i;
i = 0;
while(s1[i] != '\0' && s2[i] != '\0')
i++;
if(s1[i] == '\0')
return (s1);
else
return (s2);
}
В первом примере по умолчанию тип возвращаемого значения функции add определен как int. Функция имеет класс памяти static. Это значит, что она
Во втором примере посредством объявления typedef создан структурный тип STUDENT. Далее определена функция sortstu с типом возвращаемого значения STUDENT, функция возвращает тот из своих двух аргументов структурного типа, элемент id которого меньше.
В третьем примере определена функция, возвращающая указатель на значения типа char. Функция принимает в качестве аргументов две символьные строки (точнее, два указателя на массивы типа char) и возвращает указатель на более короткую из строк.
Формальные параметры
Формальные параметры — это переменные, которые принимают значения, переданные функции при вызове, в соответствии с порядком следования их имен в списке параметров.
Форма объявления формальных параметров аналогична использованию метода прототипов в объявлении функции. Список объявлений параметров содержит объявления формальных параметров через запятую. После списка сразу начинается тело функции (составной оператор). Список может быть и пустым, но и в этом случае он должен быть ограничен круглыми скобками. Если функция не имеет аргументов, рекомендуется указать это явно, записав в списке объявлений параметров ключевое слово void.
После последнего идентификатора в списке параметров может быть записана запятая с многоточием (,…). Это означает, что число параметров функции переменно, однако не меньше, чем следует идентификаторов до многоточия.
Для доступа к значениям параметров, имена которых не заданы в списке параметров функции, рекомендуется использовать макроопределения va_arg, va_end, va_start, описанные в разделе 12.
Допускается также список параметров, состоящий только из многоточия (…) и не содержащий идентификаторов. Это означает, что число параметров функции переменно и может быть равно нулю.
Примечание. Для совместимости с программами предыдущих версий компилятор допускает запись символа запятой без многоточия в конце списка параметров для обозначения их переменного числа. Запятая может быть использована вместо многоточия и в том случае, когда надо записать список параметров функции, принимающей нуль или более параметров. Использование запятой поддерживается только для совместимости. Для новых программ рекомендуется использовать многоточие.
Объявления параметров имеют тот же самый синтаксис, что и обычные объявления переменных (смотри раздел 3.4). Формальные параметры могут иметь базовый тип, либо быть структурой, объединением, указателем или массивом. Указание первой (или единственной) размерности для массива не обязательно. Массив воспринимается как указатель на тип элементов массива. Для формального параметра, таким образом, эквивалентны объявления
char s[];
char s[10];
char *s;
Параметры могут иметь класс памяти auto или register. Если спецификация класса памяти опущена, то подразумевается класс памяти auto. Если формальный параметр представлен в списке параметров, но не объявлен, то предполагается, что он имеет тип int. Порядок объявления формальных параметров необязательно должен совпадать с порядком их следования в списке параметров, однако для повышения читабельности программы рекомендуется следовать этому порядку.