Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Программирование 1

.pdf
Скачиваний:
29
Добавлен:
20.03.2016
Размер:
1.04 Mб
Скачать

7.9 Рекурсивные вызовы функции

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

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

А

Рисунок 7.1 – Прямая рекурсия

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

А

B

C

 

Рисунок 7.2 – Косвенная рекурсия

 

Любая функция в программе на языке СИ может быть вызвана рекурсивно, т.е. она может вызывать саму себя. Компилятор допускает любое число рекурсивных вызовов. При каждом вызове для формальных параметров и переменных с классом памяти auto и register выделяется новая область памяти, так что их значения из предыдущих вызовов не теряются, но в каждый момент времени доступны только значения текущего вызова.

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

Классический пример рекурсии - это математическое определение факториала n! :

n! = 1 при n=0; n*(n-1)! при n>1 .

Функция, вычисляющая факториал, будет иметь следующий вид: long fakt(int n)

{

return ( (n==1) ? 1 : n*fakt(n-1) );

61

}

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

7.10 Примеры составления функций

Пример 1. Написать функцию, которая вычисляет объем цилиндра. Параметрами функции должны быть радиус и высота цилиндра.

#include <stdio.h> #include <conio.h> #include <math.h>

float veil(float h, float r) {return(M_PI*r*r*h);} void main ()

{

float r,h; float v;

puts("Вычисление объема цилиндра"); printf("Введите высоту и радиус основания ->"); scanf ("%f%f", &h, &r) ;

v = veil(h, r);

printf("Объем цилиндра %3.2f\n", v); printf("Для завершения нажмите <Enter>"); getch();

}

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

int max(int a, int b) {if (a > b) return(a); else return(b);

}

Пример 3. Написать функцию, которая сравнивает два целых числа и возвращает результат сравнения в виде одного из знаков: >, < или =.

#include <stdio.h> #include <conio.h>

char compare(int a, int b)

{

char res;

if (a > b) res = '>';

else if (a < b) res = '<'; else res = '=';

62

return(res);

}

void main()

{

int xl,x2; // сравниваемые числа char res; // результат Сравнения puts("Введите два целых числа и нажмите <Enter>"); printf("->");

scanf("%i%i", &xl, &x2);

res = compare(xl,x2); // вызов функции программиста printf("%i %c %i\n", xl, res, x2);

puts("\nДля завершения работы программы нажмите <Enter>"); getch();

}

Пример 4. Написать функцию, обеспечивающую решение квадратного уравнения. Параметрами функции должны быть коэффициенты и корни уравнения. Значение, возвращаемое функцией, должно передавать в вызывающую программу информацию о наличии корней уравнения: 2 — два разных корня, 1 — корни одинаковые, 0 — уравнение не имеет решения. Кроме того, функция должна проверять корректность исходных данных. Если исходные данные неверные, то функция должна возвращать -1.

#include "stdio.h" #include "conio.h" #include "math.h"

int kvadur(float a, float b, float с, float *xl, float *x2)

//значение функции - количество корней

//или -1, если неверные исходные данные

{

float d; // дискриминант if (a == 0) return(-1);

d = b*b-4*a*c;

if (d < 0) return(0); // уравнение не имеет решения

*xl = (-b+sqrt(d))/(2*a); *х2 = (-b-sqrt(d))/(2*a); if (*xl != *х2) return(2); else return(1);

}

void main()

{

float a,b,c; // коэффициенты уравнения float xl,x2; // корни уравнения

int n; // кол-во корней

puts("\nРешение квадратного уравнения");

puts("Введите в одной строке коэффициенты и нажмите <Enter>"); printf("->");

63

scanf("%f%f%f", &a, &b, &c); switch (kvadur(a,b,c,&xl,&x2))

{

case -1: puts("Ошибка исходных данных."); break; case 0: puts("Уравнение не имеет решения.");break; case 1: printf("Корни одинаковые: x=%3.2f", xl) ;break; case 2: printf("xl=%3.2f x2=%3.2f", xl, x2);

}

puts("\n Для завершения работы нажмите <Enter>"); getch();

}

64