Продолжение, начало см. в МК № 3, 8 (226, 231). Вы все еще рубите нечисть окровавленным мечом или спасаете заложников от верной смерти? Так вот почему вы не услышали звонок! А ну-ка дружно нажали на кнопочку Save. Вот так-то лучше, теперь начнем наш урок.

Сначала, как всегда, разберемся с домашним заданием. Вот задачка, которую я задавал:

Задача № 7

Составить программу, которая вычисляет период (в годах), за который первоначальный вклад в сберегательный банк удвоится. Первоначальный вклад и процент годовых начислений должен вводиться оператором READLN_._

С этим заданием нужно быть очень осторожным. Помните, как иногда бывало на математике: вроде бы пример простенький, но сделали вы его неправильно. А все дело в том, что в нем есть изюминка, которая все портит. Вот так и с этой задачей. Нельзя забывать, что процент начисляется не к начальной сумме, а к той, которая на счету. То есть, если первоначальным вкладом было 100 зеленых, а процент годовых начислений равнялся 10%, то после второго года 10% добавится к 110$ (100$ + 10%) и будет составлять $11, а не $10. Вот мое решение этой задачи:

var vklad, percent, period: integer; // Объявляем переменные vkl: Real; begin writeln('Введите вклад и процент годовых начислений:'); Read(vklad, percent); // Считываем с клавиатуры вклад и процент vkl := vklad; repeat vkl := vkl + (vkl/100*percent); // Увеличиваем сумму на счету на заданный процент Inc(period); // Увеличиваем количество лет на единицу until vklad*2 < vkl; // Если вклад не удвоился, то продолжаем его увеличивать writeln('Первоначальный вклад удвоится за ', period, ' лет.'); // Выводим результат end.

Как видите, все достаточно просто. Попробуйте сами написать программку, которая вычисляет период не только в годах, но и в месяцах. Например, если моя программка пишет, что первоначальный вклад удвоится через 4 года, то ваша должна писать, что он удвоится через 3 года и 7 месяцев или что-нибудь в этом роде…

А сейчас давайте разберемся со следующей задачей:

Задача № 8

Массив размером 45 заполнить следующим образом: четные строки — числом 2, нечетные — числом 3. Составить программу создания массива и полученный массив вывести на экран в виде матрицы.

var mas: array[1..4,1..5] of 2..3; // Объявляем массив i, i1: integer; // Объявляем переменные begin for i := 1 to 4 do // Внешний цикл, который изменяет номер строки begin for i1 := 1 to 5 do // Внутренний цикл, который изменяет номер столбца begin if i mod 2 = 0 then mas[i,i1] := 2 else mas[i,i1] := 3; write(mas[i,i1], ' '); end; writeln; end; end.

Четность или нечетность строки можно узнать, разделив номер строки на два. Остаток будет равен нулю, если строка парная, и единице, если непарная.

Ну что, размялись? Пора бы решить задачу посложнее:

Задача № 9

Составить программу заполнения массива 56 случайными числами из интервала от 1 до 9. Вычислить произведение всех элементов массива, а также произведение элементов без третьей строки и четвертого столбца.

Мало того, что эта задача сложнее, она еще и с приколом :-). Произведением всех элементов массива может оказаться очень большое число. «Ну и что?» — скажите вы, — «Тип Integer поддерживает числа вплоть до 32767». Но если подумать и посчитать, то произведение будет намного большим, и даже тип LongInt не сможет его охватить, в большинстве случаев. И тут на помощь нам приходит вещественный тип Real. Казалось бы, все проблемы решены. Но результат может удивить вас. Еще бы, ведь вы ожидали получить самое обычное число, а в итоге получилось что-то типа 1.85787014065422E+0018. Давайте разберемся, что это такое. Я постараюсь объяснить все как можно проще.

Такое представление числа называется формой записи с экспонентой. Число при этом представляется в виде множителя, называемого мантиссой, умноженного на 10 в какой-то степени. Это можно показать так: ЧИСЛО=МАНТИССА*10k, где k — степень (порядок). Например: 4.3E+3 = 4.3*103 = 4.3*1000 = 4300, то есть мантисса 4.3 умножается на 10 в третьей степени; -2.284E-5 = -2.284*10-5 = -2.284*0.00001 = -0.00002284, то есть отрицательная мантисса -2.284 умножается на 10 в минус пятой степени или 0.00001.

Вещественные типы имеют одну очень интересную особенность. Если целочисленной (Integer) переменной присвоить значение 2.1 и вывести ее на экран, то мы увидим 2.1. Но если вместо целочисленной взять вещественную (Real) переменную, то получим… 2.09999999999854E+0000, то есть на 0.0000000000146 меньше, чем 2.1. Вот это и есть та особенность — результат никогда не будет абсолютно точным. Чтобы добиться большей точности, можно использовать более точные вещественные типы. Например, если в указанном выше примере переменная будет иметь тип Extended, то результатом будет 2.10000000000000E+0000, или 2.1. Но если присвоить данной переменной значение 2.123456789012345, то результат будет немножечко другим: 2.12345678901235E+0000. Разница очень маленькая и состоит только в последней цифре 5.

Кстати, если вы захотите заполнить массив большими числами, то тип Real «не потянет» их произведение, и вам придется использовать дополнительные вещественные типы, такие как Single, Double, Extended, Comp. Но учтите, если у вас в опциях (команда меню Options > Compiler) не отмечен крестиком пункт 8087/80287, то компилятор выдаст сообщение об ошибке.

Это все, что я хотел сказать о вещественных типах. Теперь перейдем к решению задачи:

var mas: array[1..5,1..6] of 1..9; // Объявляем массив proizv, proizv1: Real; // Объявляем переменные i, i1: Integer; begin Randomize; // Инициализируем генератор случайных чисел proizv := 1; proizv1 := 1; for i1 := 1 to 6 do begin for i := 1 to 5 do begin mas[i,i1] := Random(9) + 1; // Заполняем массив случайными целыми числами от 1 до 9 write(mas[i,i1], ' '); // Выводим массив на монитор proizv := proizv * mas[i,i1]; // Вычисляем произведение всех элементов if (i>4) or (i<4) or (i1>3) or (i1<3) then proizv1 := proizv1 * mas[i,i1]; // Вычисляем //произведение всех элементов без третьей строки и четвертого столбца end; writeln; // Переводим курсор на новую строку end; writeln; // Пропускаем пустую строку для красоты writeln('Произведение всех элементов = ', proizv); // Выводим результат writeln('Произведение без 3 строки и 4 столбца = ', proizv1); end.

Думаю, что больше нет надобности застревать на этой задаче, поэтому давайте решим следующую.

Задача №10

Линейный массив размерностью N заполнить случайными числами из интервала от A до B. Найти сумму всех чисел.

Данная задача имеет две особенности. Во-первых, не указана размерность массива, а если написать m: array[1..n] of Integer, то при компиляции получите ошибку: Cannot evaluate this expression, что переводится как «не могу оценить это выражение». «Как же быть?» — скажете вы. Все очень просто. Если нам не сообщили размерность массива, то мы сами ее укажем — с запасом. Например, можно написать m: array[1..20000] of Integer. Мало не покажется :-). Правда, можно использовать динамический массив, но это совсем другая, причем не такая уж и простая история.

Во-вторых, нам не дан строгий интервал чисел для заполнения массива. Но и эта проблема решается достаточно просто. Нужно написать x := Random(B-A+1) + A. Если задуматься, то становится понятно, что минимальное случайное число будет 0+A=A, а максимальное B-A+A=B. Единицу мы добавляем, так как функция Random возвращает случайное число в диапазоне _0<=X 75 then writeln; // Переводим курсор на следующую строку, если предыдущая заполнена почти до конца write(mas[i], ' '); // Выводим массив на экран end; writeln('Сумма всех чисел = ', symma); // Выводим результат end.`

Вот и закончился очередной урок; осталось только задать домашнее задание:

Задача № 11

Ввести в программу три числа. Разделить максимальное на минимальное. Вывести на экран значение трех данных чисел и полученный результат.

До следующих встреч на страницах МК!