Главная

Популярная публикация

Научная публикация

Случайная публикация

Обратная связь

ТОР 5 статей:

Методические подходы к анализу финансового состояния предприятия

Проблема периодизации русской литературы ХХ века. Краткая характеристика второй половины ХХ века

Ценовые и неценовые факторы

Характеристика шлифовальных кругов и ее маркировка

Служебные части речи. Предлог. Союз. Частицы

КАТЕГОРИИ:






Int top, bottom, temp;




for (top=0, bottom = n-1; top<bottom; top++, bottom--)

{

temp = vector[top];

vector[top] = vector[bottom];

vector[bottom] = temp;

}

}

Эта функция переворачивает вектор vector[n] – выполняет «поплавок».

Более того, при передаче в функцию вектора можно не указывать его длину, оставляя квадратные скобки за его именем пустыми:

void poplavok(int n, int vector[])

Обратимся к этой функции из головной программы:

#include <stdio.h>

#include <conio.h>

void poplavok(int n, int vector[]); // прототип функции

Int main()

{

int i, k=5;

int vect[k] = {1,2,3,4,5}; // инициализация вектора

printf("\n"); // вывод исходного вектора

for (i=0; i<k; i++)

printf("%5d", vect[i]);

printf("\n");

poplavok(k, vect); // обращение к функции

for (i=0; i<k; i++) // вывод полученного вектора

printf("%5d", vect[i]);

printf("\n");

printf("\n");

}

void poplavok(int n, int vector[]) // описание функции

{

Int top, bottom, temp;

for (top=0, bottom = n-1; top<bottom; top++, bottom--)

{

temp = vector[top];

vector[top] = vector[bottom];

vector[bottom] = temp;

}

}

На экран будет выведено:

1 2 3 4 5

5 4 3 2 1

Если в качестве формального параметра функции используется многомерный массив, то в заголовке функции после его имени в отдельных квадратных скобках указываются все его размеры:

void vorm_mass(int n, int m, int mass[n][m])

{

Int i, j;

for (i=0; i<n; i++)

for (j=0; j<m; j++)

{

mass[i][j]=i + j;

}

}

Обратимся к этой функции из головной программы:

#include <stdio.h>

#include <conio.h>

void vorm_mass(int n, int m, int mass[n][m]); // прототип

Int main()

{

Int i, j;

int k=2, d=3;

int massiv[k][d];

vorm_mass(k, d, massiv); // обращение к функции

printf("\n");

for (i=0; i<k; i++) // вывод полученного массива

{ // построчно

for (j=0; j<d; j++)

printf("%5d", massiv[i][j]);

printf("\n");

}

}

void vorm_mass(int n, int m, int mass[n][m])

{ // описание функции

Int i, j;

for (i=0; i<n; i++)

for (j=0; j<m; j++)

{

mass[i][j]=i + j;

}

}

Результат работы программы:

0 1 2

1 2 3

 

Рекурсия

Использование рекурсии в программировании базируется на рекурсивных математических определениях. Считается, что в математике рекурсивность как принцип определений используется с 1890 года. Впервые ее применил Д. Гильберт.

Основная идея рекурсии – определить некий объект через самого себя, по крайней мере частично. Оказалось, что с помощью рекурсии удобно описывать различного рода последовательности, подчиняющиеся определенным закономерностям.

Например, вычисление факториала целого неотрицательного числа n! = 1·2·3·…·(n-1) · n. Кроме того, по определению, 0! = 1. Рекурсивное математическое определение факториала имеет вид

1 при n = 0,

n!=(n – 1)!·n при n > 0.

 

Последовательность чисел Фибоначчи имеет вид 1, 1, 2, 3, 5, 8, 13…

В ней два первых числа фиксированы и равны единице, а каждое последующее число равно сумме двух предыдущих. Рекурсивное математическое определение числа Фибоначчи с порядковым номером n имеет вид:

1 при n = 1,

1 при n = 2,

Fn=Fn-2 + Fn-1 при n > 2.

 

Общей особенностью этих рекурсивных определений является то, что некий сложный объект определяется через себя же (рекурсивно обращается к себе же), но в более простом исполнении. Рекурсивные математические определения отличаются особой лаконичностью, что и подтверждается вышеприведенными примерами.

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

Рассмотрим последовательность факториалов целых чисел 0!, 1!, 2!, 3!, …, в которой ai = i!, i = 1, 2, 3, …. Эту же последовательность можно представить в виде рекуррентной формулы: ai = ai-1·i, a0 = 1, i = 1, 2, 3… Эта формула задает последовательность, в которой каждый очередной член зависит непосредственно от предшествующего. Начальный член последовательности a0 задан прямою. Найдя член последовательности с порядковым номером i = n, мы тем самым решим задачу вычисления n!

Рекуррентная формула для вычисления числа Фибоначчи с заданным порядковым номером i = n практически не отличается от рекурсивного определения :

Fi = Fi-2 + Fi-1, F1 = 1, F2 = 1, i = 3, 4, 5,…

Итак, функция считается рекурсивной, если при решении задачи она обращается к самой себе или непосредственно, или через другие подпрограммы. Известно, как технически реализуется обращение к подпрограмме в общем случае:

1) запоминается состояние программы, вызывающей подпрограмму, – адрес точки, следующей за оператором обращения к подпрограмме, чтобы знать, куда вернуться после ее выполнения,

2) в свободном месте памяти располагаются все необходимые локальные переменные вызываемой подпрограммы, а также копии тех ее параметров, которые передаются по значению,

3) выполняются операторы подпрограммы, затем освобождается временно занятая область памяти, после чего осуществляется возврат в нужную точку программы, вызвавшей подпрограмму.

При рекурсивном обращении каждый раз приходится запоминать не только адрес возврата, но и всю совокупность данных вызывающей подпрограммы (локальные переменные и параметры-значения). С этой целью используется автоматически выделяемая область памяти – стек, структура, работающая по принципу LIFO (Last in – first out: последним пришел – первым вышел). Такой метод работы с памятью обеспечивает строгое соответствие прямого порядка записи данных обратному порядку их чтения. Только с помощью стека можно достаточно просто обеспечить корректное завершение работы цепочки подпрограмм, каждая из которых вызывает следующую: сначала должна быть завершена последняя, затем – предпоследняя и так далее. Максимальный размер стека – 65520 байт. Поэтому последовательность рекурсивных обращений не может быть бесконечной. В любой рекурсивной подпрограмме должна быть нерекурсивная (терминальная) ветвь, обеспечивающая выход из рекурсии. При переполнении стека работа программы прерывается и появляется сообщение об ошибке.

Рекурсивная функция, вычисляющая факториал заданного числа n, может иметь вид:






Не нашли, что искали? Воспользуйтесь поиском:

vikidalka.ru - 2015-2024 год. Все права принадлежат их авторам! Нарушение авторских прав | Нарушение персональных данных