Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015

Тут можно читать онлайн Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - бесплатно полную версию книги (целиком) без сокращений. Жанр: Прочая старинная литература, издательство Вильямс, год 0101. Здесь Вы можете читать полную версию (весь текст) онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.

Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015 краткое содержание

Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - описание и краткое содержание, автор Стивен Прата, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - читать онлайн бесплатно полную версию (весь текст целиком)

Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - читать книгу онлайн бесплатно, автор Стивен Прата
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Отсутствие аргументов и неопределенные аргументы

Предположим, что вы создали прототип следующего вида:

void print_name();

Компилятор ANSI С предположит, что вы решили воспользоваться стилем объявления, предшествующим прототипированию, и не будет проверять аргументы. Для отражения того, что функция не принимает аргументов, укажите в круглых скобках ключевое слово void:

void print_name(void);

Функции 341

Компилятор ANSI С интерпретирует предыдущее выражение как то, что функция print name() не имеет аргументов. Затем он проверяет, не применяете ли вы аргументы при вызове этой функции.

Некоторые функции, такие как printf() и scanf(), принимают переменное количество аргументов. Например, в printf() первым аргументом является строка, но остальные аргументы не фиксированы ни по типам, ни по количеству. Для таких случаев стандарт ANSI С разрешает частичное прототипирование. Например, для printf() можно было бы использовать такой прототип:

int printf(const char *, ... );

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

Заголовочный файл stdarg.h в библиотеке функций С предоставляет стандартный способ для определения функции с переменным количеством параметров; детали будут раскрыты в главе 16.

преимущество прототипов

Прототипы являются мощным дополнением к языку. Они позволяют компилятору выявлять многие ошибки или оплошности, которые могли быть допущены при использовании функций. Если их не обнаружить своевременно, они превратятся в проблемы, которые могут оказаться трудными для отслеживания. Обязаны ли вы применять прототипы? Нет, вы вполне можете использовать старый метод объявления функций (без указания параметров), но никакими преимуществами он не обладает, взамен имея множество недостатков.

Существует один способ избежать прототипа, одновременно сохранив преимущества прототипирования. Причиной указания прототипа является сообщение компилятору о том, как должна использоваться функция, до достижения им первого фактического случая ее применения. Того же результата можно добиться, поместив полное определение функции до ее первого использования. В этом случае определение действует как собственный прототип. Чаще всего это делается с короткими функциями:

Рекурсия В языке С функции разрешено вызывать саму себя Этот процесс - фото 250

Рекурсия

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

342 Глава 9

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

Рекурсия в действии

Давайте взглянем на пример рекурсии. Функция main() в листинге 9.6 вызывает функцию up and down(). Назовем это “первым уровнем рекурсии”. Затем функция up and down() вызывает саму себя; назовем это “вторым уровнем рекурсии”. Второй уровень вызывает третий уровень рекурсии и т.д. В этом примере настроены четыре уровня рекурсии. Чтобы посмотреть, что происходит внутри, программа не только отображает значение переменной n, но также и значение &п, которое представляет собой адрес ячейки памяти, где хранится переменная n. (Операция & более подробно обсуждается позже в главе. Для вывода адресов в printf() применяется спецификатор %р. Если ваша система не поддерживает этот формат, попробуйте воспользоваться спецификатором %u или %lu.)

Листинг 9.6. Программа recur.с

Вывод на одной из систем выглядит следующим образом Уровень 1 ячейка n - фото 251

Вывод на одной из систем выглядит следующим образом:

Уровень 1: ячейка n 0x0012ff48 Уровень 2: ячейка n 0x0012ff3c Уровень 3: ячейка n 0x0012ff30 Уровень 4: ячейка n 0x0012ff24 УРОВЕНЬ 4: ячейка n 0x0012ff24 УРОВЕНЬ 3: ячейка n 0x0012ff30 УРОВЕНЬ 2: ячейка n 0x0012ff3c УРОВЕНЬ 1: ячейка n 0x0012ff48

Давайте пройдемся поданной программе, чтобы посмотреть, как работает рекурсия. Сначала main() вызывает up_and_down() с аргументом 1. В результате формальный параметр n функции up_and_down() получает значение 1, поэтому первый оператор вывода отображает строку Уровень 1:. Далее, поскольку n меньше 4, функция up_and_down() (уровень 1) вызывает функцию up_and_down() (уровень 2) с фактическим аргументом n + 1, или 2. Это приводит к тому, что n в вызове уровня 2 присваивается значение 2, так что первый оператор вывода отображает строку Уровень 2 :. Аналогично, следующие два вызова приводят к выводу Уровень 3: и Уровень 4:.

Функции 343

Когда достигнут уровень 4, переменная n равна 4, поэтому проверка в i f не проходит. Функция up and down() не вызывается снова. Вместо этого вызов уровня 4 продолжается выполнением второго оператора вывода, который отображает строку УРОВЕНЬ 4:, т.к. переменная n имеет значение 4. В этой точке вызов уровня 4 заканчивается, а управление возвращается функции, которая его инициировала (вызов уровня 3). Последним оператором, выполненным внутри вызова уровня 3, был вызов уровня 4 в операторе if. Следовательно, выполнение уровня 3 возобновляется со следующего оператора, которым является второй оператор вывода. Это приводит к отображению строки УРОВЕНЬ 3:. Затем уровень 3 завершается, передавая управление уровню 2, который выводит строку УРОВЕНЬ 2 :, и т.д.

Обратите внимание, что на каждом уровне рекурсии применяется собственная закрытая переменная n. Этот факт легко установить, взглянув на значения адресов. (Конечно, в общем случае в разных системах адреса будут отличаться и возможно иметь другие форматы. Важный момент заключается в том, что адрес в строке Уровень 1: совпадает с адресом в строке УРОВЕНЬ 1: и т.д.)

Если вы находите приведенное объяснение слегка запутанным, то представьте, что имеется цепочка вызовов функций, в которой funl() вызывает fun2(), fun2() вызывает fun3() и fun3() вызывает fun4(). Когда fun4() завершается, управление передается fun3(). По завершении fun3() управление передается fun2(). Когда заканчивается fun2(), управление возвращается обратно fun1(). Рекурсивный случай работает точно так же, за исключением того, что функции fun1(), fun2(), fun3() и fun4() являются одной и той же функцией.

основы рекурсии

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

Во-первых, каждый уровень вызова функции имеет собственные переменные. То есть переменная n уровня 1 отличается от переменной n уровня 2, так что программа создает четыре разных переменных, каждая из которых имеет имя n и собственное значение, отличающееся от других. Когда в конечном итоге программа возвращается к вызову функции up and down() первого уровня, исходная переменная n по-прежнему имеет значение 1, с которого она начинала (рис. 9.4).

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Стивен Прата читать все книги автора по порядку

Стивен Прата - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




Язык программирования C. Лекции и упражнения (6-е изд.) 2015 отзывы


Отзывы читателей о книге Язык программирования C. Лекции и упражнения (6-е изд.) 2015, автор: Стивен Прата. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x