Какова цель этой линии? (Объявление функции)

Я работаю над K & R, чтобы научиться программированию. Хорошо продвигаться до сих пор, но я не понимаю о роли строки кода из раздела 1.8 (функции).

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

Я наклеил код ниже, как написано в книге. Все выводится нормально. Но я не знаю, почему они включили эту строку вверху:

int power(int m, int n); 

В книге не упоминается об этом, кроме того, что программа будет поднять целое число m до степени n. Если я удалю строку из кода, программа по-прежнему будет выводиться так, как должна.

Если я правильно понимаю это, строка

 int power(int base, int n) 

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

Так что все это имеет смысл. Но я не понимаю, что делает сама верхняя линия.

Это может быть посторонним, но кажется гораздо более вероятным, что я что-то пропустил. Может ли кто-нибудь просветить меня, почему эта линия есть?

 #include  int power(int m, int n); /* test power function */ main() { int i; for (i = 0; i = 0 */ int power(int base, int n) { int i, p; p = 1; for (i = 1; i <= n; ++i) p = p * base; return p; } 

Первая строка – это объявление функции. Блок кода внизу – это определение функции.

Начиная с версии стандарта ISO C 1999 года, это незаконно (нарушение ограничения) для вызова функции без видимого объявления; объявление должно предшествовать вызову.

Для простой программы, такой как эта, вы можете просто написать полное определение power() перед определением main() (поскольку определение также содержит объявление), но для более сложных случаев (например, рекурсивных вызовов) вам часто требуется для предоставления отдельной декларации.

Для больших программ обычно собирают все объявления функций в файле заголовка (например, foo.h ) и соответствующие определения в исходном файле (например, foo.c ). Директива #include "foo.h" используется, чтобы сделать объявления видимыми в других файлах. Вы увидите это позже в книге.

(В 1990-х и более ранних версиях C, что охватывает K & R2, есть случаи, когда вы можете вызывать функцию без видимого объявления, но в любом случае все равно очень хорошая идея предоставлять явные объявления).

Кстати, декларация основной программы действительно должна быть int main(void) а не просто main() .

Терминология: «прототип» – это объявление функции, определяющее типы параметров.

 int power(int base, int n); /* a declaration that's also a prototype */ int power(int, int); /* likewise */ int power(); /* a declaration but not a prototype */ 

(Имена параметров требуются в определении, но необязательно в отдельной декларации.)

В качестве особого случая прототип функции без параметров использует (void) , поскольку пустые круглые скобки уже означают объявление без прототипа. Таким образом, int main(void) является прототипом, но int main() – нет.

Непротопические декларации являются «устаревшими», что означает, что теоретически они могут быть удалены из будущего языкового стандарта. Но с 1989 года они устарели, и даже в новом стандарте ISO C 2011 года комитет не счел нужным их удалить.

 int power(int m, int n); 

является объявлением power функции в ее прототипной форме. Объявление функции информирует компилятор о числе параметров, которые имеет функция, тип параметров функции и тип возвращаемого значения функции.

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

Это предварительное объявление, которое делает интерфейс функции общедоступным, поскольку функция используется до того, как она фактически будет реализована ниже main() .

Заголовочные файлы, которые вы #include предоставляют аналогичную функциональность для создания общедоступного API-интерфейса, но этот код обычно предоставляется в библиотеке, а не через один и тот же блок компиляции, как здесь, в этом примере из одного файла K & R Введение.

Если вы не включаете эту строку вверху, когда программа достигает power(2,i) основная мощность еще не объявлена. Программы читаются сверху вниз, и, помещая объявление вверху, компилятор знает, что «определение приближается».

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

Эта строка вверху, о которой вы говорите, является прототипом функции. Единственная вещь, в которой она существует, – это то, что компилятор может проверить вашу работу, то есть убедиться, что вы правильно используете эту функцию, передавая правильные типы и количество аргументов. Это все, для чего. Вот почему вы можете удалить его, и код все еще компилируется – все, что вы делаете, удаляя его, удаляет ссылку компилятора, чтобы он не мог проверить вашу работу. И если вы удалите его, тогда есть вероятность, что вы можете передать неправильный тип аргументов и вызвать сложную ошибку времени выполнения или сбой программы. Но оставляя его, позволяет компилятору отмечать такую ​​ошибку во время компиляции, сохраняя при этом некоторое горе. И спасти кого-то горе – это хорошо.

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