- •2.2.Функции, возвращающие значение
- •Void main ()
- •Void Sum(float *s,float *X, int n)
- •Void main ()
- •Void Sumstmatr ( float (*mz)[m], float *mx, int n1, int m1); //прототип функции Sumstmatr
- •Void main ()
- •Void Sumstmatr (float (*mz)[m], float *mx, int n1, int m1)
- •Void main ()
- •Void main()
- •2.3. Функции обработки строк
- •Void strcpy ( char *s, char *t)
- •Void strcpy ( char *s, char *t)
- •Int strcmp ( char * s, char * t)
- •Unsigned strlen (const char *str );
- •Void strcpy (char *s,char *t);
- •Void main ()
- •Int Vs(char *s, char *sl, int d);
- •Int Vs(char *s,char *sl, int d) // функция формирования очередной строки
- •2.4. Рекурсивные функции
- •Void main()
- •3.Классы памяти и области действия описаний
- •Автоматические переменные
- •Внешние переменные
- •Void main ()
- •Void main ()
- •Int a[4]; // указано, что а – локальный массив целого типа
- •Void main ()
- •Статические переменные
- •Void f();
- •Void main ()
- •Void f()
- •Регистровые переменные
- •4.Элементы структурного программирования
- •4.1.Нисходящая разработка
- •4.2.Основные структуры, пошаговая детализация
- •Void main ()
- •Void main ()
- •Void Smog (long mz[][n2]);
- •Void main ()
- •Void Smog (long mz[][n2])
- •4.3.Сквозной структурный контроль
- •Элементы, которые должны проверяться на контрольных сессиях
2.4. Рекурсивные функции
Рекурсивнойназывают функцию, которая прямо или косвенно сама вызывает себя.Именно возможность прямого или косвенного вызова позволяет различатьпрямую или косвенную рекурсию.
При каждом обращении к рекурсивной функции создается новый набор объектов автоматической памяти, локализованных в теле функции.
Функция называетсякосвенно рекурсивной, если она содержит обращение к другой функции, содержащей прямой или косвенный вызов определяемой (первой) функции. В этом случае по тексту определения функции ее рекурсивность (косвенная) не видна.
Если в теле функции явно используется вызов этой же функции, то функция называется прямой рекурсивной функцией.
Рассмотрим классический пример - функцию для вычисления факториала неотрицательного целого числа:
#include<conio.h>
#include<iostream.h>
#include <stdio.h>
long fact (int N);
Void main()
{ long k,ff;
clrscr();
printf("k=");
scanf("%d",&k);
ff = fact(k);
printf("ff= %d\n",ff);
getch();
}
long fact (int N)
{ if (N < 0) return 0;
if (N==0) return 1;
return fact (N-1)*N;
}
В этой программе использована рекурсивная функция fact.В теле функции имеется оператор returnfact(N-1)*N;, в котором имеется обращение функции к самой себе (fact(N-1)*N). Для отрицательного аргумента результат (по определению факториала) не существует. В этом случае функция возвратит нулевое значение. Для нулевого параметра функция возвращает значение 1 (по определению 0! Равен 1). В противном случае вызывается та же функция с уменьшенным на 1 значением параметра. Тем самым для положительного значения параметра N организуется вычисление произведения
N* (N – 1)* ( N –2)* …*3*2*1
Последовательность рекурсивных обращений к функции factпрерывается при вызове
fact(0).Именно этот вызов приводит к последнему значению 1 (if(N==0)return1;) в произведении, так как последнее выражение, из которого вызывается функция, имеет вид fact(1-1). Процесс выполнения функции factиллюстрируется на рис.12. Обратите внимание, что в начале процесс идет слева направо (вызываются рекурсивно функции), а затем, когда появилась первая вычисленная функции (fact(0)), осуществляются возвраты справа налево.
В последующем изложении нашего курса мы познакомимся с динамическими информационными структурами, которые включают рекурсивность в само определение данных. Именно для таких данных применение рекурсивных функций наиболее эффективно.
3.Классы памяти и области действия описаний
Одно из достоинств языка Си состоит в том, что он позволяет управлять ключевыми механизмами программы. Классы памяти – пример такого управления. Они дают возможность определить, с какими функциями связаны какие переменные и как долго сохраняются они в программе.
Каждая переменная программы имеет тип. Это мы знаем. Но кроме этого каждая переменная принадлежит к определенному классу памяти. Класс памяти определяет область действия переменной и продолжительность ее существования в оперативной памяти. Класс памяти устанавливается при описании переменной с соответствующим ключевым словом. Есть четыре ключевых слова, используемых для описания класса памяти:
auto – автоматический класс (временное существование, область действия – локальная);
extern – внешний класс (постоянное существование, область действия –глобальная);
static - статический класс (постоянное существование, область действия – локальная);
register – регистровый класс (временное существование, область действия – локальная, размещение – в регистрах центрального процессора, к которым доступ выполняется гораздо быстрее, чем в оперативной памяти).