С прототип функции - PullRequest
       2

С прототип функции

6 голосов
/ 06 февраля 2011

Как новичок в C, я могу понять необходимость использования прототипов функций в файле, но не уверен в нескольких вещах.

Во-первых, требует ли каждый вызов функции за пределами main объявления прототипа? Есть ли условия, где это может измениться?

Во-вторых, вам нужен отдельный прототип функции для перегрузок методов?

Ответы [ 4 ]

8 голосов
/ 06 февраля 2011

Вызовы функций в C не требуют, чтобы прототип был видимым, но настоятельно рекомендуется, чтобы в области видимости находился правильный прототип.

Причина этого заключается в том, что если определение функции не соответствуеттипы аргументов функции после выполнения продвижений аргументов функции по умолчанию весьма вероятно, что вы получите неопределенное поведение.

Наличие правильного видимого прототипа означает, что компилятор может проверить аргументы вызова функции и предупредить программиста, еслиимеется несоответствие.

C не допускает перегрузки функций, поэтому вы можете иметь только один прототип для любого имени функции.

Повышение аргументов по умолчанию может привести к неожиданным несовпадениям.

Например,

int main(int argc, char **argv)
{
    short s = 5;
    float f = 2.3f;
    x(s, f);     // x implicitly declared; default argument promotions performed
    return 0;
}

int x(short t, float g)  // Error: called with an int and a double
{
    return (int)(t + g);
}

В вызове функции, поскольку x не имеет видимого прототипа (пока), s будет повышен до int, а f будет увеличен до double.Это продвижение аргументов по умолчанию .Это тогда вызывает несоответствие, когда функция определена с прототипом, который принимает short и float, даже если это оригинальные типы аргументов, которые были переданы.

Функции, которые принимают переменнуюколичество аргументов (т. е. использование синтаксиса , ...) всегда должно иметь видимый прототип в той точке, в которой они вызываются.

4 голосов
/ 06 февраля 2011

Другие уже отмечали, что C не требует прототипов для функций. Я просто добавлю пару мелких очков.

Прежде всего, без прототипа аргументы функции всегда проходят «продвижение по умолчанию» перед передачей в качестве параметров, поэтому (например) все меньшие целочисленные типы повышаются до int, а float получает повышен до double. Поэтому без прототипа функция не может получить (например) char, short или float. Если функция определена для получения одного из этих типов, будет несоответствие между тем, что передано, и тем, что ожидает функция, что дает неопределенное поведение (любое другое несоответствие также дает неопределенное поведение).

Во-вторых, если функция определена с помощью списка переменных аргументов, то вам нужно нужен прототип для нее, иначе вызов ее приведет к неопределенному поведению.

1 голос
/ 06 февраля 2011

Нет, функции не обязаны иметь прототипы.Однако они полезны, так как позволяют вызывать функции до их объявления.Например:

int main(int argc, char **argv)
{
    function_x(); // undefined function error
    return 0;
}

void function_x()
{

}

Если вы добавите прототип выше main (это обычно делается в заголовочном файле), это позволит вам вызвать function_x, даже если оно определено после main.Вот почему, когда вы используете внешнюю библиотеку, которую необходимо связать, вы включаете заголовочный файл со всеми прототипами функций в нем.

C не имеет перегрузки функций, поэтому это не имеет значения.

0 голосов
/ 06 февраля 2011

Нет.В C не каждая функция требует прототипа.НО это хорошая практика, чтобы включить его.Прототипы помогают компилятору отлавливать ошибки.Конечно, некоторые компиляторы C по умолчанию жалуются на отсутствие прототипов перед вызовом функции, но это поведение не обязательно является стандартом.

Приведенная выше логика применима и к перегрузкам.

Конечно, поскольку вы новичок в C. Я думаю, вам лучше поискать разницу между Прототипом и Определением функции, чтобы иметь полный смысл.

...