Формальные и фактические параметры
Коль скоро формальные параметры функции являются псевдопеременными, которые при вызове содержат копии фактических параметров, на них распространяются все соглашения о типах данных и переменных. В частности, в заголовке функции используется стандартный контекстный способ определения типа переменной:
void f(char **p, int A[], void (*f)())
{...}
абстрактными типами данных формальных параметров.
Исторически сложилось, что первоначальный синтаксис определения функции принципиально исключал возможность контроля транслятора за соответствием количества и типов формальных и фактических параметров. С одной стороны, это позволяло использовать механизм вызова функций и передачи параметров нестандартными способами, а, с другой стороны, являлось причиной многочисленных, трудно обнаруживаемых ошибок. В связи с этим был введен новый синтаксис определения, а также объявления функции, называемый прототипом. Если вызывается функция, определенная или объявленная по прототипу, то транслятор проверяет соответствие формальных и фактических параметров и, по возможности, выполняет неявные преобразования типов.
// Прототип
int strcmpn(char *p1,char *p2,int n){___}
void f(void){___} // или
void f(){___}
int printf(char *s, ...){___}
extern double sin(double);
extern void f(void);
extern int printf(char*,...);
// Традиционный синтаксис
int strcmpn(p1,p2,n)
char *p1,*p2;
int n;
{___}
void f() {___}
int printf(s,a)
char *s;
int a;
{___}
extern double sin();
extern void f();
extern int printf();
Прототип отличается от традиционного синтаксиса следующим:
-в заголовке определения функции по прототипу формальные параметры указаны в скобках в контексте, определяющем их тип. В традиционном синтаксисе в скобках указаны только имена формальных параметров, а контекстное определение их типов выполняется отдельными строками перед открывающейся скобкой тела функции ("{");
-при объявлении внешней функции в традиционном синтаксисе список параметров вообще отсутствует, в то время как в объявлении с использованием прототипа в скобках перечисляются абстрактные типы данных формальных параметров или их контекстные определения;
-если функция допускает переменное количество параметров, то переменная часть списка в определении и в объявлении функции по прототипу обозначается псевдо-параметром " ... ";
-если функция не имеет параметров, то в объявлении по прототипу в скобках должен быть указан тип void (чтобы не спутать с традиционным синтаксисом объявления).