Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Стохастический_мир.pdf
Скачиваний:
112
Добавлен:
16.03.2016
Размер:
2.96 Mб
Скачать

Глава 9

Компьютерное моделирование

Иногда моделирование на компьютере поведения сложных стохасти- ческих систем единственный способ их исследовать. Эта глава рассчи- тана на Читателя, который любит не только формулы, но и алгоритмы. Программирование лишь запись на очень ограниченном и формализованном английском языке ч¼тко фиксированной последовательности действий. Эта последовательность может быть выполнена человеком, компьютером или инопланетянином. Любая из программ легко переводится на человеческий язык, однако результат будет занимать больше места и, в силу неоднозначности естественного языка, может иметь множественное толкование. Глава не предназначена для обучения программированию на языке C++. Для этого лучше обратиться к любому из много-

численных пособий. В то же время мы по ходу дела будем приводить некоторые особенности C++, которые помогут чтению текста программ.

233

234

Глава 9.

9.1Основы языка C++

Компьютер оперирует с целыми (int) и вещественными ( oat) числами. Каждое число хранится в переменной с определ¼нным названием. Чтобы опечатка в е¼ имени не привела к недоразумению, все переменные перечисляются до их использования:

int

i ,

j;

 

//

объявлены дв е целые переменные i , j

float

x ,

y ,

z;

//

три вещественные переменные x , y , z

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

x

=

3.5; y = 2;

//

зада¼м начальные

значения x и y

z = x*y;

//

вычисляем

z , êàê

èõ

ï ð î è ç â å ä å í è å

x

=

-(z+y )/3;

//

x теперь

принимает

новое значение

Все действия алгоритма осуществляются сверху вниз и слева направо, поэтому переменная x сначала равна 3.5, затем, после вычисления z =

7 = 3:5 2, в третьей строке изменяет сво¼ значение на -3. Кроме ариф-

метических операций, существует большое число математических функций, например, sin(x), натуральный логарифм log(x), и т.д. В качестве

разделителя десятичных разрядов используется точка.

При работе с целыми числами необходимо помнить о некоторых особенностях. Если в арифметическом выражении присутствуют только целые числа, то и результат получится целым. Иногда это может привести к неожиданным эффектам. Так, 7/2 равно 3 (целая часть), а не 3.5, как было бы в случае вещественных чисел.

Необходимо также помнить, что компьютер не способен проводить вы- числения с бесконечной точностью. Для целых чисел это означает, что существует максимальное значение, выше которого будет происходить переполнение. Для 32-х разрядных компьютеров целые числа по модулю меньше, чем 2'147'483'648.

Аналогичная проблема существует и для вещественных чисел. Они ограничены как по размеру, так и по точности (количеству сохраняемых разрядов числа). Для вычислений, требующих высокой точности, лучше работать не с oat, à ñ double вещественными переменными, дающимидвойную точность по сравнению с oat. Мы будем для обозначения вещественных чисел использовать тип Float, который может быть или обычным вещественным, или вещественным с удвоенной точностью.

Компьютерное моделирование

235

Для этого в самом начале программы необходимо вставить строку:

typedef double Float ;

// вещественный тип ,

которая во вс¼м коде заменит Float на double. При желании всегда можно вернуться к более быстрому типу oat, изменив только одну эту строку.

C-подобные языки обладают рядом сокращ¼нных обозначений, которые делают их очень лаконичными. Так, очень часто при вычислении суммы необходимо прибавлять к переменной число, а результат сложения снова помещать в эту же переменную. Для сокращения этой операции используется следующая запись:

x +=2;

//

эквивалентно

x

=

x

+

2

x ++;

//

эквивалентно

x

=

x

+

1

Знак ++ в названии языка обозначает переход на один уровень выше по сравнению с его прародителем, языком C. Аналогично, существуют операторы =, *=, /= и .

Операторы увеличения ++ и уменьшения числа на единицу мож-

но ставить как после переменной, так и перед ней. Если оператор стоит перед переменной, то она сначала изменяется, а только затем участвует в вычислениях. Если же оператор стоит после переменной, то е¼ изменение производится в последнюю очередь. Так, если x=1, то выражение y = (x++); привед¼т к y=1, а выражение y = ( ++x); к значению y=2.

Аналогично и для оператора .

Настоящий алгоритм начинается при появлении операции ветвления:

if (x <2)

//

если x меньше 2 ,

y =5;

//

то y присвоить значение 5

Сразу после if точка с запятой не ставится, так как мысль ещ¼ не закончена. Двигаясь сверху вниз по алгоритму и дойдя до такой команды, компьютер проверяет текущее значение переменной x, и только в том

случае, если она меньше двух, присваивает y значение 5. Иначе переменная y не изменяется и программа выполняется дальше. Условный оператор может иметь и блок иначе :

if (x <2)

// если x меньше 2 ,

y =5;

// то y присвоить 5

else {

//

иначе :

y =7; z =8;

//

y присвоить 7 , а z 8 .

}

 

 

Если в блоках if èëè else выполняется не одно, а несколько действий, то они заключаются в фигурные скобки f::g. В качестве условий можно

использовать символ равенства переменных x==y и неравенства x!=y.

236

Глава 9.

Некоторые действия приходится делать повторно. Для этого служат

операторы цикла while è for. Оператор while выполняет набор команд, заключ¼нных в фигурные скобки, до тех пор, пока истинно выражение, стоящее в круглых скобках (подобно оператору if). Так, если необходимо просуммировать целые числа от 1 до 9, мы должны написать:

int

sum

=

0;

// начальное значение суммы

 

int

i =

1;

 

// п е р в о е число

 

while (i <10){

//

пока i <10 , выполняем в с ¼ в

{ . . }

 

sum

+=

i;

// суммируем целые числа от 1

äî 9

 

i ++;

 

 

//

увеличиваем i на единицу :

i=i +1

}

Первоначально целая переменная i имеет значение 1. Внутри фигурных скобок она вс¼ время увеличивается на единицу и добавляется в переменную sum. Все это происходит до тех пор, пока i меньше 10. Таким образом получается результат sum=1+2+...+9=45.

Оператор for имеет три секции: инициализация, условие, при котором цикл продолжается, и операция, производящаяся в конце каждой итерации. Код для суммирования целых чисел, эквивалентный приведенному выше, имеет вид:

int sum

=

0;

 

// начальное значение суммы

 

for ( int

i =1;

i <10; i ++)

//

с i =1 , пока i <10 , увеличивать

i

sum

+=

i;

//

суммируем целые числа от 1 до

9

Если в списке операторов, которые необходимо выполнять, несколько раз используется только один оператор, фигурные скобки можно не ставить. Отступы перед операторами, попадающими под действие команд if, while èëè for, делаются для повышения читаемости кода.

Внутри циклов можно использовать команды break; èëè continue;. Первая прекращает выполнение цикла и выходит из блока операторов. Вторая, наоборот, продолжает выполнение цикла, но приводит к проверке, не выполняя в данном такте цикла операторы, идущие ниже continue;.

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

int sum = 0, i =1;

//

начальное значение суммы и числа

while (1){

// бесконечный цикл

 

if (i >=10) break ;

//

прекращение цикла ,

åñëè i >=10

sum += i;

//

суммируем целые числа от 1 до 9

i ++;

//

увеличиваем сч¼тчик

íà 1

}

 

 

 

В C++ любое целое число, отличное от нуля, считается истиной , поэтому цикл while(1) никогда не останавливается. Однако, если i больше

или равно 10, оператор break его прерывает.

Компьютерное моделирование

237

При работе с данными их необходимо где то хранить. Для этого слу-

жат массивы. Они представляют собой обычные переменные, которые в математике мы обозначаем величиной с индексом ai, bi. При объявлении массива в квадратных скобках зада¼тся количество его элементов. В массив можно сразу поместить набор чисел, перечислив их через запятую в фигурных скобках:

float

a [10];

// массив из 10 чисел

 

float

b [3] = {1 , 3, 0};

//

массив из

3 х чисел :

1 , 3 , 0

a [0]

= 5* b [2];

//

операции

с элементами

массива

Массивы в языке C++ имеют нумерацию с нуля. Поэтому первый элемент массива это a[0], а последний a[9] (b[0] и b[2] соответственно).

Результаты работы программы обычно выводятся на экран или в

файл. Для этого служит функция printf. Первым е¼ аргументом является строка, заключ¼нная в двойные кавычки, в которой могут располагаться произвольный текст и команды, определяющие, как необходимо форматировать выводимые числа. Собственно числа, которые выводятся, перечисляются через запятую после строки форматирования. Команды форматирования всегда начинаются со знака процента %. Их количе- ство и последовательность должны совпадать с переменными, идущими после строки форматирования:

printf ("Ku - ku \n" ); // вывод строки и п е р е х о д ниже printf ("i =%d ,j =% d" , i ,j ); // вывод двух целых (%d ) переменных printf ("x =% g\n" , x ); // вывод вещественного (%g ) числа printf ("x =%4.2 f\n" , x ); // то же, с 2 мя десятичными знаками

Минимальная программа, которую пойм¼т компилятор и которая

выведет на экран (в консоль) надпись Hi Stochastic World! , имеет следующий вид:

# include < stdio .h >

// подключение библиотеки вывода

void main ()

// главная процедура программы

{

 

printf ("Hi Stochastic

World !\n");

}

 

Основной кусок кода void main(){...} является главной процедурой, тело которой, находящееся в фигурных скобках, начинает выполняться при запуске программы. Воспользовавшись бесплатными компиляторами bcc32.exe или gcc.exe, можно откомпилировать этот текст, помещ¼нный в файл hi.cpp , в выполняемый файл hi.exe при помощи командыbcc32.exe hi.cpp .