char s[10];
char *s;
Параметры могут иметь класс памяти auto или register. Если спецификация класса памяти опущена, то подразумевается класс памяти auto. Если формальный параметр представлен в списке параметров, но не объявлен, то предполагается, что он имеет тип int. Порядок объявления формальных параметров необязательно должен совпадать с порядком их следования в списке параметров, однако для повышения читабельности программы рекомендуется следовать этому порядку.
Идентификаторы формальных параметров не могут совпадать с идентификаторами переменных, объявляемых внутри тела функции, но возможно локальное переобъявление формальных параметров внутри вложенных блоков функции.
В объявлениях формальных параметров не может быть объявлен никакой другой идентификатор, кроме перечисленных в списке параметров. Если функция имеет переменное число параметров, то программист отвечает и за определение их числа при вызове, и за получение их из стека внутри тела функции.
Тип каждого формального параметра должен соответствовать типу фактического аргумента и типу соответствующего аргумента в списке типов аргументов функции, если имеется предварительное объявление функции со списком типов аргументов. Компилятор выполняет преобразования по умолчанию отдельно над типом каждого формального параметра и над типом каждого фактического аргумента.
После преобразования все формальные параметры имеют тип размером не меньше, чем int, и ни один из формальных параметров не имеет тип float. Это означает, например, что объявление формального параметра с типом char эквивалентно его объявлению с типом int, а объявление с типом float эквивалентно объявлению с типом double.
Если используются модификаторы near, far, huge, то компилятор также может неявно провести преобразование аргументов-указателей. Метод преобразования в этом случае зависит от размера указателей в выбранной модели памяти и от наличия или отсутствия списка типов аргументов функции.
Тип каждого формального параметра (после преобразования) определяет, как интерпретируются размещенные в стеке аргументы. Несоответствие типов фактических аргументов типам формальных параметров может привести к неверной интерпретации. Например, если в качестве аргумента передается 16-битовый указатель, а соответствующий формальный параметр объявлен как 32-битовый, тоне 16, а 32 бита стека проинтерпретируются как аргумент. Эта ошибка повлияет не только на аргумент-указатель, но и на другие аргументы, которые следуют за ним. От ошибок такого рода может предохранить использование объявления функции со списком типов аргументов.
Пример:
struct student {
char name [20];
int id;
long class;
struct student *nextstu;
} student;
main(void)
{
int match(struct student *, char *);
.
.
.
if(match (student.nextstu, student.name) > 0) {
.
.
.
}
}
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);
}
В примере содержатся: объявление структурного типа student, определение главной функции, содержащей предварительное объявление функции match и ее вызов, и определение функции match. Обратите внимание на то, что одно и то же имя student используется без противоречия для тега структуры и имени структурной переменной.
Функция match объявлена с двумя аргументами. Первый аргумент — указатель на структуру типа student, второй — указатель на значение типа char.
В определении функции match заданы два формальных параметра, r и n. Параметр r объявлен как указатель на структуру типа student. Параметр n объявлен как указатель на значение типа char. По умолчанию, для функции match подразумевается тип возвращаемого значения int.
Функция match вызывается с двумя аргументами. Оба аргумента являются элементами переменной структурного типа student с именем student.
Поскольку имеется предварительное объявление функции match, компилятор проверит соответствие типов фактических аргументов в операторе ее вызова списку типов аргументов, а затем соответствие типов фактических аргументов типам формальных параметров. В данном случае несоответствия типов нет и в преобразованиях нет необходимости.
Обратите внимание на то, что имя массива, заданное в качестве второго аргумента в вызове функции, преобразуется по умолчанию к указателю на char. В функцию передается не сам массив, а адрес начала массива. Соответствующий формальный параметр также объявлен как указатель на char, а мог бы быть объявлен и как char n[], поскольку в выражении используется как идентификатор массива. Идентификатор массива рассматривается в выражении как адресное выражение, поэтому объявление формального параметра char *n; эквивалентно объявлению char n[];.
Внутри функции объявляется локальная переменная i, используемая в качестве индекса массива. Функция возвращает структурный элемент id, если структурный элемент name совпал с содержимым массива n; в противном случае функция возвращает нулевое значение.