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

Курс лекций CS (первый семестр)

.pdf
Скачиваний:
7
Добавлен:
20.05.2015
Размер:
2.69 Mб
Скачать

Кафедра теоретической механики ИМЭМ ОНУ им. И.И.Мечникова

Лекция №22.

Рекурсия.

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

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

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

Чтобы показать пример решения проблемы с помощью рекурсии, рассмотрим ряд Фибоначчи:

1,1,2,3,5,8,13,21,34 …

Каждое число ряда (после второго) представляет собой сумму двух стоящих впереди чисел. Задача состоит в том, чтобы, например, определить n-й член ряда Фибоначчи. Одним из способом решения этой проблемы лежит в тщательном анализе этого ряда. Первые два числа равны 1. Каждое последующее число равно сумме двух предыдущих. В общем случае n-е число равно сумме (n-2)-го и (n-1)-го при условии, если n<3.

При этом используется следующий алгоритм:

1.Предлагается пользователю указать номер, какой член в ряду Фибоначчи следует считать.

2.Вызываем функцию fib(), передавая в качестве аргумента порядковый номер члена ряда Фибоначчи, заданный пользователем.

3.В функции fib() выполняется анализ аргумента (n). Если n<3, функция возвращает значение 1; в противном случае функция fib() вызывает самое себя (рекурсивно), передавая в качестве аргумента значение n-1, затем снова вызывает самое себя, передавая в качестве аргумента значение n-2, а после этого возвращает сумму.

using System;

using System.Collections.Generic; using System.Text;

namespace ConsoleApplication1

{

151

Кафедра теоретической механики ИМЭМ ОНУ им. И.И.Мечникова

class Program

{

static int fib(int n)

{

Console.Write("Processing fib({0})…",n); if (n<3)

{

Console.WriteLine("Return 1!"); return 1;

}

else

{

Console.WriteLine("Call fib({0})and fib({1})",n-2,n-1); return (fib(n-2)+fib(n-1));

}

}

static void Main(string[] args)

{

int n,answer;

Console.Write("Введите число:");

n=Convert.ToInt32(Console.ReadLine());

Console.WriteLine();

answer=fib(n);

Console.WriteLine("{0} есть {1} -е число Фибоначчи", answer,n);

}

}

}

Результат.

152

Кафедра теоретической механики ИМЭМ ОНУ им. И.И.Мечникова

Функция Main().

Теперь, когда вы познакомились почти со всеми простыми способами, применяемыми для создания и использования функций, давайте вернемся назад и более подробно рассмотрим функцию Main(). Как было сказано ранее, функция Main о является точкой входа в приложение на С# и выполнение этой функции охватывает выполнение приложения. У этой функции имеется параметр — string [] args, однако до сих пор мы его не описывали. В данном разделе вы познакомитесь с этим параметром и узнаете, каким образом его можно применять.

Существуют четыре различные сигнатуры, которые можно использовать для функции Main():

static void Main()

static void Main(string*+ args)

static int Main()

static int Main(string*+ args)

При желании аргумент args можно опускать. Причина, по которой мы до сих пор пользовались вариантом с этим аргументом,— в том, что такая версия генерируется автоматически при создании консольного приложения в VS. Третья и четвертая версии сигнатуры, приведенные выше, возвращают значение типа int, которое может быть использовано для указания на то, каким образом завершилось выполнение приложения, и которое часто используется для определения ошибки (хотя это в любом случае является обязательным). Обычно, возвращаемое значение равно 0, что означает "нормальное" окончание (т. е. приложение закончило свою работу и может быть завершено в безопасном режиме).

Параметр args функции Main() представляет собой метод, позволяющий приложению получать извне информацию, задаваемую в процессе его выполнения. Эта информация принимает форму

153

Кафедра теоретической механики ИМЭМ ОНУ им. И.И.Мечникова

параметров командной строки. Когда производится запуск приложения из командной строки, то при этом очень часто имеется возможность непосредственно задать некоторую информацию, например, имя файла, загрузка которого требуется для выполнения приложения. В качестве примера давайте рассмотрим Windows-приложение Notepad. Запустить его можно, просто набрав notepad — либо в окне командного приглашения, либо в окне, которое появляется при выборе опции Run (Выполнить) из меню Start (Пуск). Однако в этих же окнах мы можем набрать нечто вроде: notepad "myfile.txt". В результате Notepad либо загрузит файл myfile.txt, либо, если такого файла не существует, предложит его создать. В данном случае "myfiie.txt" является аргументом командной строки. Мы можем сами написать консольное приложение, которое будет работать аналогичным образом, использовав параметр args. Когда консольное приложение запускается, то все заданные параметры командной строки помещаются в массив args. В дальнейшем эти параметры могут использоваться по мере необходимости.

Давайте рассмотрим пример выполнения таких действий. Создадим приложение со следующим программным кодом:

using System;

using System.Collections.Generic; using System.Text;

namespace ConsoleApplication1

{

class Program

{

static void Main(string[] args)

{

Console.WriteLine("{0} command line arguments were specified:",args.Length);

foreach (string arg in args) Console.WriteLine(arg);

}

}

}

Зададим командную строку следующим образом:

1. Выбираем пункт меню Project| ConsoleApplication1 Properties. При этом загрузится окно вида:

154

Кафедра теоретической механики ИМЭМ ОНУ им. И.И.Мечникова

2. Выбираем закладку Debug и имеем окно вида:

Вэтом окне задается командная строка в поле Command line arguments, например PRIVET.

3.Запускаем приложение и имеем результат вида:

155

Кафедра теоретической механики ИМЭМ ОНУ им. И.И.Мечникова

156

Кафедра теоретической механики ИМЭМ ОНУ им. И.И.Мечникова

Лекция №23.

Функции структур.

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

Пример.

using System;

using System.Collections.Generic; using System.Text;

namespace ConsoleApplication1

{

struct student

//описание структуры

{

public char[] name; public float rost; public double massa; public void Vivod()

{

Console.Write("Cтудент "); foreach (char i in name)

Console.Write(i);

Console.WriteLine(" имеет рост {0} и вес {1}", rost, massa);

}

}

class Program

{

static void Main(string[] args)

157

Кафедра теоретической механики ИМЭМ ОНУ им. И.И.Мечникова

{

student Oleg;

Oleg.name = new char[] {'I','v','a','n','o','v',' ','O','l','e','g'};

Oleg.rost=1.88f;

Oleg.massa=60.78;

Oleg.Vivod();

Console.ReadLine();

}

}

}

Результат.

Замечание. Функция-член структуры должна быть объявлена со спецификатором public, как и все другие члены структуры.

Перегрузка функций.

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

using System;

using System.Collections.Generic; using System.Text;

namespace ConsoleApplication1

{

158

Кафедра теоретической механики ИМЭМ ОНУ им. И.И.Мечникова

class Program

{

static void F()

{

int h = 9;

}

static int F(int k)

{

return k++;

}

static void Main(string[] args)

{

F();

}

}

}

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

Пример.

using System;

using System.Collections.Generic;

using System.Text;

namespace ConsoleApplication1

{

class Program

{

static int MaxVal(int [] a,int n)

{

int max = a[0];

159

Кафедра теоретической механики ИМЭМ ОНУ им. И.И.Мечникова

for (int i = 0; i < n; i++) if (a[i] > max)

max = a[i]; return max;

}

static double MaxVal(double [] a, int n)

{

double max = a[0];

for (int i = 0; i < n; i++) if (a[i] > max)

max = a[i]; return max;

}

static void Vivod(int[] a, int n)

{

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

Console.WriteLine(a[i]);

Console.WriteLine();

}

static void Vivod(double[] a, int n)

{

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

Console.WriteLine( a[i]);

Console.WriteLine();

}

static void Main(string[] args)

{

Random ty=new Random(); int n = 10;

int[] mas1 = new int[n];

160