Язык Си в примерах/Факториал: различия между версиями

Содержимое удалено Содержимое добавлено
Нет описания правки
Уточнения; оформление примеров; →‎Задания: отмена Special:Diff/109775 — см. [[{{TALKPAGENAME}}#Целесообразность вычисления]].
Строка 16:
factorial (int n)
{
return (n < 2) ? 1 : n * factorial (n - 1);
}
 
Строка 22:
main (void)
{
int n;
while (scanf ("%d", &n) == 1) {
printf ("%d\n", factorial (n));
}
return 0;
}
</source>
 
ЭтоОпределение определениефункции <code >factorial</code> выше основано на следующей ''рекуррентной''
формуле:
 
Строка 55 ⟶ 56 :
Возможность рекурсии ограничена предельной глубиной ''стека возврата.'' В некоторых случаях, однако, реализация языка программирования может самостоятельно свести рекурсию к итерации.
 
В примере ниже, мы воспользуемся [[w:Хвостовая рекурсия |хвостовой рекурсией,]] сведение которой к итерации хотя и не требуется стандартом, но все же реализуется, например, компилятором C, входящим в распространенный комплект [[w:GNU Compiler Collection |GCC.]] Для этого, нам потребуется определить вспомогательную функцию <code >factorial_1</code>, вычисляющую значение <var >p</var> <var >n</var>!, где <var >p</var>, <var >n</var> — аргументы функции.
 
<strong >Обратите внимание</strong>, что в этом примере мы не приводим определениени определения функции <code >main</code>, ни ''директив препроцессора'' <code >#include</code> подключения используемых нами ''заголовков''егоих следует заимствовать из [[#factorial.c |предыдущего примера.]]
 
<source lang="c">
#include <stdio.h>
 
static int
factorial_1 (int n, int p)
{
return (n < 2) ? p : factorial (n - 1, p * n);
}
 
Строка 71 ⟶ 70 :
factorial (int n)
{
return factorial_1 (n, 1);
}
</source>
Строка 80 ⟶ 79 :
 
<source lang="c">
#include <stdio.h>
 
static int
factorial (int n) {
int r;
for (r = 1; n > 1; r *= (n--))
;
return r;
}
</source>
Строка 97 ⟶ 94 :
# Улучшите программы, добавив к ним диагностику ошибки во входных данных: если <var >n</var> &lt; 0, то программа должна ясно сообщать о неопределенности факториала для отрицательных чисел.
# Опытным путем определите максимальные значения аргумента и результата для программ выше. Исследуйте влияние на эти значения замены используемого в программах [[Язык Си в примерах/Скалярные типы#Числовые типы |числового типа]] <code >int</code> на <code >short</code>, <code >long</code> и <code >long long</code>. <strong >Обратите внимание</strong>, что при этом также потребуется соответственно изменить ''строку формата'' (первый аргумент) функции <code >printf</code>.
# Определите также максимальные значения аргумента и результата для программ выше при использовании [[w:Число с плавающей запятой |чисел с плавающей запятой]] — [[Язык Си в примерах/Скалярные типы#Числовые типы |числовых типов]] <code >double</code>, <code >float</code>, <code >long double</code>.
# После выполнения первых двух заданий Вы поймете, что максимальной натуральной число по которому возможно вычислить факториал с использованием 4-х байтовых беззнаковых чисел это 12 (всего навсего). Настоящий программист не будет использовать рекурсии и умножать в цикле, а использует предвычисленный статический массив готовых данных. Попробуйте и сравните быстродействие.
 
== См. также ==