Если объявление функции не задано, то по умолчанию строится прототип функции на основе анализа первой ссылки на функцию, будь то вызов или определение функции. Однако такой прототип не всегда согласуется с последующим определением или вызовом функции. Рекомендуется всегда задавать прототип функции. Это позволит компилятору либо выдавать диагностические сообщения при неправильном использовании функции, либо корректным образом регулировать несоответствие аргументов, устанавливаемое при выполнении программы.
В соответствии с синтаксисом языка С-51, определение функции имеет следующую форму:
[Спецификатор класса памяти] [Спецификатор типа] Имя функции
'(' [Список формальных параметров]')'
'{ 'Тело функции' }'
Необязательный
Функция не может возвращать массив или функцию, но может возвращать указатель на любой тип, в том числе и на массив, и на функцию.
Тип возвращаемого значения, задаваемый в определении функции, должен соответствовать типу в объявлении этой функции.
Функция возвращает значение, если ее выполнение заканчивается оператором return, содержащим некоторое выражение. Указанное выражение вычисляется, преобразуется, если необходимо, к типу возвращаемого значения и возвращается в точку вызова функции в качестве результата.
Если оператор return не содержит выражения или выполнение функции завершается после выполнения последнего ее оператора (без выполнения оператора return), то возвращаемое значение не определено. Для функций, не использующих возвращаемое значение, в описателе типа должен быть использован тип void, указывающий на отсутствие возвращаемого значения. Если функция определена как возвращающая некоторое значение, а в операторе return при выходе из нее отсутствует выражение, то поведение вызывающей функции после передачи ей управления может быть непредсказуемым, поэтому транслятор с языка программирования проверяет такую ситуацию и выдает сообщение об ошибке.
Если функция не использует параметров, то наличие круглых скобок обязательно, а вместо списка параметров рекомендуется указать слово void.
Порядок и типы формальных параметров должны быть одинаковыми в определении функции и во всех ее объявлениях. Типы фактических параметров при вызове функции должны быть совместимы с типами соответствующих формальных параметров. Формальный параметр может иметь любой основной тип, а также быть структурой, объединением, перечислением, указателем или массивом. Параметр, тип которого не указан, считается имеющим тип int.
Для формального параметра можно задавать класс памяти register, при этом для величин целого типа спецификатор типа можно опустить.
Идентификаторы формальных параметров используются в теле функции в качестве ссылок на переданные при вызове значения. Они не могут быть переопределены в блоке, образующем тело функции, но могут быть переопределены во внутреннем блоке внутри тела функции. Несоответствие типов фактических аргументов и формальных параметров может быть причиной неверной интерпретации.