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

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

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

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

int power(int m, int n);

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

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

int power(int base, int n)

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

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

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

#include <stdio.h>

int power(int m, int n);

/* test power function */
main()
{
int i;

    for (i = 0; i < 10; ++i)
        printf("%d %d %d\n", i, power(2,i), power(-3, i));
    return 0;
}

/* power: raise base to n-th power; n >= 0 */

int power(int base, int n)
{
    int i, p;

    p = 1;
    for (i = 1; i <= n; ++i)
        p = p * base;
    return p;
}

6 ответов

Решение

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

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

Для такой простой программы, как эта, вы можете просто написать полное определение 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 Intro.

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

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

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

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

Другие вопросы по тегам