Конспект лекций по предмету "Психология"

Узнать цену работы по вашей теме


Общая схема решения задачи на персональном компьютере

Введение

Учебное пособие написано на основе курса лекций, читаемых студентам 1-2 курсов математического факультета. Может быть полезно начинающим программистам, желающим самостоятельно изучить основы программирования на языке Object Pascal или слушающим соот­ветствующий лекционный курс. Предполагается, что читатель хотя бы в минимальной степени знаком с операционными системами DOS и Windows и понимает, например, что такое имя файла, каталог, папка, диск, путь и т.п. Информация о средах программирования Turbo Pascal и Borland Pascal, ориентированных на работу с DOS, а также о среде программирования Delphi, предназначенной для разработки приложений, работающих под управлением операционной системы Windows, в пособии не приводится. Отмечены лишь некоторые важные моменты. Учебное пособие содержит примеры, записанные как фрагмент программы или законченная программа. Все примеры оттестированы. Однако авторы хотели бы предостеречь от некритического использования этих программ читателем - большинство из них лишь иллюстрирует возможности языка и не претендует на оптимальность. В пособие включена подборка вариантов задач по основным темам.

1. Общая схема решения задачи на персональном компьютере

В общем виде процесс решения задачи на ПК можно представить в виде последовательности следующих действий:
1) анализ задачи;
2) разработка алгоритма решения задачи;
3) разработка пользовательского интерфейса;
4) написание кода;
5) отладка программы;
6) тестирование программы;
7) составление документации.
Все эти этапы (иногда в неявной форме) обязательно выполняются любым программистом при решении любой задачи. Рассмотрим их подробнее.
На этапе анализа задачи необходимо четко определить постановку задачи, убедиться, что вы ясно ее понимаете; определиться с набором входных и выходных данных.
Под алгоритмом понимают понятное и точное предписание исполнителю выполнить последовательность действий, направленных на достижение поставленной цели. Обязательной составной частью алгоритма является определение зависимости между входной и выходной информацией. При решении некоторых наиболее тривиальных задач может показаться, что этап разработки алгоритма отсутствует, однако это означает лишь, что вы пользуетесь уже известным вам алгоритмом. Для разработки алгоритмов существует два наиболее популярных инструмента – это блок-схема и псевдокод. Блок-схема представляет собой диаграмму, на которой изображена последовательность выполняемых компьютером определенных действий. Различные геометрические фигуры представляют на блок-схеме различные типы процессов. Псевдокод – это текст программы, содержащий как операторы языка программирования, так и фразы на удобном для пользователя языке (английском, русском и т.д.). Ниже при помощи блок-схем будут рассмотрены основные алгоритмические структуры.
Этап разработки пользовательского интерфейса предполагает проработку такого вопроса, как определение вами той информации, которую пользователь будет видеть на экране. То есть, как и в каком формате пользователь будет вводить данные, какие дополнительные к основным результирующим данным он может получить в итоге и т.д.
На этапе написания кода вы записываете алгоритм на языке программирования. Один и тот же алгоритм можно запрограммировать множеством различных способов, но вы должны стремиться написать оптимальную программу. Хорошо написанная программа, как правило, содержит меньше ошибок и гораздо быстрее отлаживается.
Этап отладки включает в себя трансляцию программы и проверку ее на простейших тестах. Трансляция программы - это процесс перевода ее с языка программирования на машинный язык, его осуществляет спе­циальная программа - транслятор. В зависимости от порядка перевода и выполнения команд все трансляторы делят на два типа: компиляторы и интерпретаторы. Компилятор - это транслятор, преобразующий исходный код языка в машинный код и создающий таким образом выполнимый файл. Интерпретатор, в свою очередь, преобразует исходный код в машинный шаг за шагом, т.е. каждая команда преобразуется интерпретатором и сразу выполняется, затем интерпретатор преобразует следующую команду. Язык Pascal является компилируемым. При трансляции вы постепенно ис­правляете допущенные при написании программы синтаксические ошибки, сле­дите за сообщениями транслятора - он указывает, какая обнаружена ошибка и где именно. После того, как вы исправите все синтаксические ошибки, и транслятор сообщит об успешном завершении трансляции, будет создан файл с име­нем, таким же, как у вашего исходного файла, и с расширением exe(от ЕХЕcutive - выполняемый); этот файл содержит программу (в отличие от исход­ного файла, содержащего лишь текст программы), которая может быть выполнена. Необходимо отчетливо понимать, что задачей транслятора ни в коем слу­чае не является поиск ошибок в ваших программах, он сообщает о них лишь в том случае, когда не может правильно интерпретировать ваш текст. Успешно осуществив трансляцию, запустите свою программу. Не следует думать, что эта программа не содержит ошибок! Все логические ошибки, допущенные вами, остались в программе, и на этапе отладки вы должны найти их и исправить. Не существует никаких об­щих рецептов для отладки - класс программиста главным образом, как раз и проявляется в том, как он отлаживает программы. Но один полезный совет мож­но дать: аккуратно и подробно выводите при отладке все вычисляемые вашей программой величины.
После того, как вы решите, что ваша программа работает правильно (обычно это не соответствует действительности), начинайте тестирование - выполняйте программу с различными наборами входных данных, причем они обязательно должны содержать все особые случаи. Когда вы убедитесь, что ваша программа иногда работает правильно, а иногда - нет, возвращайтесь к алгоритму, пере­сматривайте его и заново повторяйте все этапы. Успешно завершив тестирова­ние, вы можете надеяться, что ваша программа верна.
Следует четко разграничивать два понятия - верная программа и хорошая программа. Всякая хорошая программа верна, но далеко не всякая верная про­грамма хороша - она может использовать неэффективный (или неэффективно запрограммированный) алгоритм, занимать много лишней памяти, быть неряш­ливо оформленной и т.д. Старайтесь писать не только верные, но и хорошие программы!
Под составлением документации понимается разработка всех материалов, описывающих назначение и принципы работы программы. Документация может быть внутренней и внешней. Внутренняя документация состоит из комментариев, включенных в код программы. С их помощью человек, не знакомый с програм­мой, может понять, как она работает. Внешняя документация содержит техниче­ское задание, блок-схемы, псевдокоды, базовые допущения и описание входных и выходных данных. Для коммерческих программ внешней документацией часто служит руководство пользователя. Главное назначение документации — позволить человеку, не являющемуся разработчиком программы, использовать ее и при не­обходимости модифицировать ее код.
Схематично полный цикл разработки программы можно представить следующим образом:

Рис.1. Полный цикл разработки программы.


Свойства алгоритмов. Основные алгоритмические структуры

В предыдущем параграфе мы рассмотрели понятие алгоритма. Каждый алгоритм должен обладать следующими свойствами:
1) дискретность – процесс решения задачи должен быть разбит на… 2) понятность – алгоритм должен быть понятен исполнителю и исполнитель должен быть в состоянии выполнить его…

Линейные алгоритмы

Простейшие задачи имеют линейный алгоритм решения. Это означает, что он не содержит проверок условий и повторений.
Пример 1. Пешеход шел по пересеченной местности. Его скорость движения по… Для проверки работоспособности алгоритма необходимо задать значения входных переменных, вычислить конечный результат…

Развилка

Достаточно часто то или иное действие должно быть выполнено в зависимости от значения логического выражения, выступающего в качестве условия. В… Пример 3. Вычислить значение функции



Циклы


Циклы используются в случае, если некоторую группу операторов требуется выполнить многократно.
Пример 5. Подсчитать количество нечетных цифр в записи натурального числа .
Идея решения. Из заданного числа выбирать из младшего разряда цифру за цифрой до тех пор, пока оно не исчерпается, т.е. станет равным нулю. Каждую нечётную цифру учитывать.

блок-схема 1 блок-схема 2
Пояснения по блок-схеме 1:

1. Ввести число
2. {подготавливаем счётчик нечётных цифр}
3. Если , переход к пункту 7
4. Если , то
5.
6. Переход к пункту 3
7. Вывод
8. Конец
Пояснения по блок-схеме 2:

1. Ввести число
2. {подготавливаем счётчик нечётных цифр}
3. Если , то
4.
5. Если , переход к пункту 3
6. Вывод
7. Конец
Задача решена двумя способами. Слева решение оформлено с использованием цикла с предусловием, справа — с постусловием.

Пример 6. Найти произведение первых натуральных чисел, кратных трём.
При составлении алгоритма учтем, что первое натуральное число, кратное 3, есть тройка, а все последующие больше предыдущего на 3.

1. Ввод
2. {накапливаем произведение}
3. {переменная для хранения чисел, кратных 3}
4.
5. Если , переход к пункту 10
6.
7.
8.
9. Перейти к пункту 5
10. Вывод
11. Конец
Пример 7. Дана последовательность, общий член которой определяется формулой . Вычислить при сумму тех ее членов, которые больше заданного числа .
При решении задачи находится очередной член последовательно и, если он больше , добавляется к сумме.

1. Ввести
2.
3.
4.
5. Сравнить с . Если , переход к пункту 10
6.
7.
8.
9. Переход к пункту 5
10. Вывод
11. Конец
В примере 5 и в примере 7 количество повторений заранее неизвестно. В первом оно зависит от количества цифр в записи натурального числа, во втором — от числа . В примере 6 количество шагов известно из условия задачи, поэтому проще и предпочтительней использовать цикл с параметром.
Блок-схемы идеально подходят для изучения азов программирования, так как позволяют наглядно и однозначно проследить последовательность выполнения этапов алгоритма. Поэтому на начальном этапе авторы рекомендуют практиковать применение блок-схем. Хотя в настоящее время блок-схемы алгоритмов используются не столь широко, как в на­чале компьютерной эры. Их популярность резко упала по ряду причин.
• Разработка блок-схемы занимает много времени.
• Блок-схемы имеют большие размеры. Блок-схема даже простой программы может достичь размера в несколько страниц.
• В блок-схеме не отражаются специфические программные конструкции, реали­зующие, например, цикл или структуру принятия решения.
Наиболее существенной причиной падения популярности блок-схем стало развитие методов структурного программирования. Большие программы делают структурирован­ными, т.е. разбитыми на отдельные модули и подпрограммы. При умелой разбивке структура каждого модуля должна быть достаточно простой, при этом необходимость использования блок-схемы отпадает. Однако иногда разбить программу на простые модули все же не удается, в таких случаях приходится использовать блок-схему программы.
Как видно из названия, псевдокодпредставляет собой "ненастоящий" код. Он состо­ит из смеси операторов языка высокого уровня и фраз на английском (или русском) язы­ке. Каждый программист пользуется собственными псевдокодами, поэтому никаких стандартов на составление псевдокодов не существует.
Псевдокоды получили широкое распространение как средство облегчения разработки программ. По сравнению с блок-схемами они обладают существенными преимущества­ми. Их написание не требует много времени. Тексты псевдокодов компактны. С их по­мощью программист может сконцентрироваться на создании алгоритма, не беспокоясь об увязке всех линий блок-схемы.
Поскольку псевдокод похож на код высокоуровневого языка, его легче преобразовать в настоящий код программы, чем блок-схему. В псевдокоде отражены специфические программные конструкции, которые используются в программе для организации циклов или структур принятия решений.

3. Консольные приложения в Delphi. Введение в язык Object Pascal. Общая структура программы. Идентификаторы, комментарии, пробелы. Раздел описаний и раздел операторов

Для реализации программ, написанных на языке программирования Object Pascal, можно использовать различные системы программирования. Turbo Pascal и Borland Pascal ориентированы на работу с дисковыми операционными системами DOS (такими как MS DOS компании Microsoft или PC DOS компании IBM). Среда программирования Delphi предназначена для разработки программ (или приложений), работающих под управлением операционной системы Windows. Мы рассмотрим возможность создания приложений для DOS в среде Delphi. Это позволит подготовиться к использованию графического интерфейса пользователя (GUI – Graphical User Interface).Такие программы называются консольными приложениями.
Создадим простое консольное приложение. Для этого выполним ряд действий.
1. Выберем команду FileNewOther (ФайлНовыйДругое), выделим пиктограмму Console Appli­cation (Консольное приложение) и щелкнем на кнопке ОК. При этом на экране появится окно редактора кода.
2. В окне редактора кода введем следующий текст (некоторые строки вам набирать не придется, они уже будут присутствовать):
program ConsoleExample;
{$APPTYPE CONSOLE}
uses SysUtils;
begin
Writeln ('Hello, World from Delphi!!!');
Writeln ('This is the console application.');
Writeln;
Writeln ('Press <ENTER> to quit.');
Readln;
end.
3. Сохраним программу, выбрав последовательно команды FileSave Project As… Затем нажмем клавишу <F9> - программа выполнится. При этом на экране появляется такое ок­но DOS:
Нажав клавишу <Enter>, завершим работу консольного приложения.
4. Особо нужно отметить сложности, возникающие при работе с кириллицей в консольных приложениях. Выполним следующую программу:
program ConsoleExample;
{$APPTYPE CONSOLE}
uses SysUtils;
begin
Writeln (‘Привет, Мир!!!');
Writeln ('Это консольное приложение.');
Readln;
end.
на экране увидим следующее

Появление такой «абракадабры» связано с тем, что в компиляторе Delphi используется кодовая страница Windows-1251, а запущенное приложение использует кодовую страницу DOS. В результате этого несоответствия русские буквы отображаются некорректно. Воспользуемся следующим способом для устранения проблемы - используем функцию, которая будет перекодировать кириллицу Windows в DOS перед отображением на экран. Важно отметить, что при наборе фрагментов 'А'..’п' и 'р'..'я' обязательно (!) включать русскую раскладку клавиатуры.
program test;
{$APPTYPE CONSOLE}
function Rus(mes: string):string;
var i: integer;
begin
for i:=1 to length(mes) do
case mes[i] of
'А'..’п' : mes[i] := Chr(Ord(mes[i]) - 64);
'р'..'я' : mes[i] := Chr(Ord(mes[i]) - 16);
end;
rus := mes;
end;
begin
Writeln (Rus('Привет, Мир!!!'));
Writeln (Rus('Это консольное приложение.'));
Readln;
end.
Результат работы программы выглядит гораздо привлекательнее:

Разъяснением содержимого последней программы мы займемся позже, после изучения ряда тем. В последующих программах оговаривать вывод кириллицы не будем, вы можете пользоваться предложенным примером.
Теперь займемся более детальным рассмотрением такого примера:
begin
writeln('Hello !!!');
Readln;
end.
Если вам удастся откомпилировать и запус­тить эту программу, она выведет на экран сообщение: " Hello !!!". Получения того же сообщения на экране можно добиться, записав программу так:
const Message=' Hello !!!';
begin
writeln(Message); Readln;
end.
и так :
var Message: String[10];
begin Message:=' Hello !!!'; writeln(Message); Readln;
end.
и еще множеством различных способов, но в каждой программе обязательно бу­дет слово begin,и в конце программы всегда будет стоять end.- признак кон­ца программы. Перед BEGINможет что-то быть (как правило, это так), или может не быть ничего. То, что находится перед BEGIN,называется разделом описаний, то, что находится между BEGINи END., называется разделом опе­раторов. Слова BEGIN, END, а также WRITELN, READLNяв­ляются ключевыми словами языка Object Pascal, а слово Message- это идентификатор пользователя, т.е. имя, данное нами некоторому объекту - константе, перемен­ной, или чему-то еще. Все ключевые слова и идентификаторы пользователя есть последовательности букв и цифр, начинающиеся с буквы. Буквами языка явля­ются все латинские буквы и символ подчеркивания. Компилятор не различает большие и малые латинские буквы, поэтому вы можете записывать идентифика­торы как захотите: Begin, BEGIN, begin, BeGiNи т.д. – компилятор будет воспринимать их одинаково. Вы можете выбирать любые идентификаторы пользователя, лишь бы они не совпадали с ключевыми словами; так, в нашем примере вместо Messageвы можете написать Qили __t123, или Y56_ertи т.д. Однако все эти идентификаторы не несут в себе никакого смысла, затрудняют чтение и отладку программы и делают ее неряшливой; идентифика­тор Message имеет то достоинство что из него уже ясно его назначение - содер­жать некоторое сообщение. Старайтесь всегда использовать в программе осмыс­ленные идентификаторы! Язык Object Pascal допускает идентификаторы длиной до 63 символов (точнее, компилятор различает первые 63 символа имени), поэтому не экономьте на именах переменных и функций, пусть лучше имена будут длин­ными, но понятными. Кроме ключевых слов и идентификаторов всякая про­грамма содержит также пробелы и (в идеале) комментарии. Комментарии могут быть запи­саны в фигурных скобках и могут стоять в любом месте программы, пробе­лы являются разделителями, там, где допустим один пробел, можно поставить любое количество пробелов. Комментарии и пробелы следует использовать для аккуратного оформления текста программы. Хорошая программа обязательно должна быть документирована, т.е. содержать комментарии поясняющие, как она работает.

4. Арифметические типы данных. Числовые константы и переменные. Оператор присваивания. Выражения

В языке Object Pascal определены следующие арифметические типы данных: це­лочисленные типы - Byte, ShortInt, Word, Integerи LongInt; вещественные типы - Real, Single, Doubleи Extended; и не совсем вещественный тип Comp. Характеристики этих типов приведены в таблице 1 (запись 1.5e-45 означает 1.5 умноженное на 10 в степени -45, это общепринятое в языках программирования обозначение для вещественных чисел - константа с плавающей точкой).
Арифметические типы данныхТаблица 1
Название типа
Диапазон допустимых значений
Количество
верных цифр
Размер
в байтах
Byte
0...255
-

ShortInt
-128...127
-

Word
0..65535
-

Integer
-32768...32767
-

LongInt
-2147483648...2147483647
-

Single
±1.5e-45... ±3.4e+38
7-8

Real
±2.9e-39... ±1.7e+38
11-12

Double
±5.0e-324... ±1.7e+308
15-16

Extended
±3.4e-4932... ±1.1e+4932
19-20

Comp
-9.2e18...9.2e18


Типы Byteи Wordиспользуются для целых величин без знака, типы ShortInt, Integerи LongInt- для целых со знаком, типы Single, Real, Doubleи Extended- для вещественных величин. Тип Compможет содержать только целые числа от -2 63 +1 до +263-1, но эти числа хранятся в вещественном формате, поэтому тип Compсчитается вещественным. С данными типа Comp можно обращаться так же, как с данными других вещественных типов, но дробная часть числа при этом автоматически отбрасывается.
Целые числовые константы записываются в языке Object Pascal в десятичном виде или в 16-ричном виде, 16-ричная константа начинается с символа $и содержит 16-ричные цифры: 0-9,A-F. Например, число 255 можно записать как $FF. Числовые константы по умолчанию имеют тип Integerили LongInt. Вещественные константы записываются либо с фиксированной точкой, например, -1.234, либо с плавающей точкой, например, -1.234E-5или 555е12.
В программе, как правило, приходится использовать переменные арифметических типов. Каждая такая переменная (и переменная любого другого типа) в языке Object Pascal должна быть обязательно описана, т.е. должен быть явно указан ее тип. Описание переменных в общем случае имеет вид:
VARимя_1,... ,имя_n :тип ;
имя_a1,... ,имя_am :тип ;...
Здесь имя - имена разных переменных (идентификаторы), тип - типы переменных, VAR- ключевое слово, означающее, что после него следуют описания переменных. Переменные одного типа можно описать совместно, разделив их имена запятыми, а можно описывать и каждую переменную отдельно. Точка с запятой означает окончание описания переменных данного типа. Слово VARможет повторяться в программе сколько угодно раз. Выбор типа для той или иной переменной определяется назначением этой переменной. Пусть, например, переменная iслужит счетчиком (индексом) элементов некоторой последовательности, причем известно, что количество элементов не может превосходить 100. Мы можем описать переменную iлюбым целочисленным типом, но правильный выбор - Byteили ShortInt, любой другой тип будет избыточным. Всегда следует выбирать типы переменных осознанно; если вы не понимаете, какой тип должна иметь ваша переменная, вероятнее всего, эта переменная в программе не нужна. Но при этом важно быть уверенным, что значение переменной не выйдет за рамки диапазона данного типа переменных. Для вещественных переменных чаще всего используется тип Singleили Extended.
Пусть в программе нам необходимы переменные b1,b2,b3,b4типа Byte, переменные i,j,kтипа Integerи переменные r1,r2типа Single. Их можно описать, например, двумя эквивалентными способами:
var b1,b2,b3,b4 : Byte;
i,j,k : Integer;
r1,r2 : Single;
или так :
var b : Byte;
i,j,k Integer;
var r1: Single;
var b2,b3,b4: Byte;
r2: Single;
Всякая переменная обладает четырьмя атрибутами: именем, типом, адресом и значением. Имя переменной есть идентификатор, т.е. последовательность символов; тип переменной определяет ее свойства, диапазон допустимых значений и размер памяти, необходимый для размещения этой переменной; адрес переменной указывает на место в памяти, где размещается ее значение; переменная всегда имеет некоторое значение, даже если вы ничего не сделали, чтобы определить это значение. В последнем случае говорят, что переменная не определена; это значит, что ее значение не известно нам заранее (ни в коем случае не следует думать, что неопределенные переменные имеют нулевые значения - это не так).
Каким же образом определить значение переменной? Для этого используется оператор присваивания:
имя := выражение;
Здесь мы встречаемся с двумя новыми понятиями - оператор и выражение. Оператор - это минимальная осмысленная конструкция в языке Object Pascal, вся программа - это последовательность операторов. Оператор всегда заканчивается символом ";", кроме одного единственного оператора END.Допускаются пустые операторы ";", не выполняющие никаких действий. Выражение - это конструкция, состоящая из одного или нескольких операндов и, возможно, знаков операций, и имеющая некоторое значение. Операндами могут быть константы, переменные и другие выражения, т.е. можно строить сколь угодно сложные выражения. Мы не знаем пока никаких знаков операций, но предположим, что знак +означает операцию сложения (это так и есть). Запишем несколько выражений:
1(константа есть частный случай выражения);
b1(переменная есть частный случай выражения);
25+1E3 b1+4.25+r2
Теперь мы можем присвоить переменной ее значение:
i:=-11; j:=22+i; k:=i+j+177;
Наряду с переменными в Паскале есть и другие именованные объекты - это константы (отличайте их от числовых констант, которые не имеют имени, а лишь значение). Константы бывают двух видов - нетипизированные и типизированные. Нетипизированные константы описываются, так же, как и переменные в разделе описаний, в виде:
const имя=значение; имя=значение; ...
Здесь имя - идентификатор, значение - вообще говоря, некоторое выражение, которое может включать и именованные константы, описанные выше, но только не переменные. Запишем несколько примеров:
const c=-155;
d=c+100;
const f=d+1;
const g=c+f;
Нетипизированные константы, описанные в разделе описаний, вы можете затем использовать в разделе операторов в выражениях, но изменить их значения невозможно. Не совсем удачное название "нетипизированные" означает не отсутствие у констант типа - любая константа имеет совершенно определенный тип, который определяется ее значением, - а лишь то обстоятельство, что при описании таких констант тип не указывается явно. Второй класс именованных констант - типизированные константы, описание которых имеет вид:
const имя:тип=значение; имя:тип=значение; ...
С этим классом констант мы работать не будем, поэтому подробное описание опускаем.

5. Ввод-вывод данных в Паскале

Для ввода-вывода данных в Паскале используются стандартные процедуры ввода-вывода, которые иногда не совсем верно называют операторами ввода-вывода. Понятие процедур и функции будет рассмотрено позднее, пока же мы просто познакомимся с особенностями их организации.
Простейшая процедура ввода в Паскале - процедура READ, она записывается в виде:
read(имя_1,имя_2,...);
где имя - имена переменных или типизированных констант. Вводимые значения задаются в виде допустимых в Паскале констант и разделяются любым количеством пробелов. Для окончания ввода следует нажать клавишу Enter. Процедуру ввода можно записать и как READLN, при вводе числовых переменных они эквивалентны. Кроме того, READLNбез списка в скобках можно использовать для организации задержки в работе программы - программа будет переходить в режим ожидания нажатия любой клавиши.
Простейшая процедура вывода записывается в виде:
write(выражение_1, выражение_2, ...);
или
writeln(выражение_1, выражение_2, ...);
Вывести можно любое выражение, если необходимо вывести текст, он заключается в апострофы. Процедура WRITELNотличается от процедуры WRITEтем, что после вывода происходит переход на новую строку. Можно использовать процедуру WRITELNбез списка вывода для пропуска строки. Запишем пример программы, осуществляющей ввод и вывод:
var i : integer;
w : word;
r : single;
begin
writeln; { ------------- ввод ------------- }
write('Введите целое число ');
read(i);
writeln;
write('Введите натуральное число ');
read(w);
writeln;
write('Введите вещественное число ');
read(r);
writeln; { ------------- вывод ------------- }
writeln('Вы ввели : ',i,' ',w,' ',r,' их сумма=',i+w+r); writeln('Нажмите Enter для выхода');
readln;
readln;
end.
Впервые записав осмысленную программу, остановимся и обсудим ее внешний вид. Даже на таком тривиальном примере мы можем понять некоторые основные правила оформления программы.
1. Организация диалога с пользователем. Прежде чем записать оператор READ,вы обязаны записать хотя бы один WRITE, который выведет на экран приглашение "Введите ...", причем из этого приглашения пользователь должен понять, какие именно данные ему следует ввести. Так, в нашем примере операторы write('Введите i '); read(i); были бы неуместны, так как пользователю неизвестно, что такое i, и он мог бы ввести, например, вещественное число, что привело бы к аварийному завершению программы.
2. Оформление текста программы. Хорошо оформленная программа легко читается и быстрее отлаживается, следует стремиться к "прозрачности" текста, но не к некоторой, вполне субъективной, "красоте". Так, скажем, операторы, выполняющиеся последовательно, следует и записывать строго друг под другом, но не "елочкой" или какой-либо другой фигурой. Средства, используемые для оформления текста, крайне просты и доступны всякому - это пробелы, пустые строки и комментарии.
3. При выводе чисел можно их форматировать, т.е. управлять формой их представления. Для этого в списке вывода после выводимого выражения можно указывать модификаторы: “:L:d“ - для вещественных значений и “:L” для вещественных и целых. L и d - целочисленные выражения, первое из них определяет, сколько всего позиций отводится для выводимого числа на экране, а второе - сколько выводится цифр после десятичной точки. Если при выводе вещественного числа задан модификатор “:L:d“, то оно выводится с фиксированной точкой, если же задан модификатор “:L” или он отсутствует - то с плавающей точкой. Пусть значение переменной Xравно 123.45678, тогда оператор
write(x); выведет " 1.2345678000E+02"
write(x:8:2); выведет " 123.46"
write(x:10:5); выведет " 1.235E+02"
write(x:10); выведет " 1.235E+02"
write(x:8); выведет " 1.2E+02"
write(x:1); выведет " 1.2E+02"
По умолчанию вещественные числа всегда разделяются при выводе пробелами, но если вы выводите подряд несколько целых чисел, не форматируя их и не выводя между ними пробелов, они будут выводиться подряд и сольются в одно число.

6. Арифметические операции. Стандартные математические функции

Для арифметических данных, т.е. для числовых констант, переменных и числовых функций определены шесть арифметических операций:
+сложение
- вычитание
*умножение
/вещественное деление
divцелая часть от деления
modостаток от деления
Первые четыре операции определены для любых операндов - как целых, так и вещественных, причем результат операции "/" всегда вещественное число, даже если оба операнда целые. Операции DIVи MODопределены только для целых операндов. Кроме того, выделяют унарную операцию "-", которая применяется не к двум, а к одному операнду, например: -x.
Вообще говоря, язык Object Pascal запрещает использовать в одном выражении разнотипные операнды, однако для арифметических данных сделано исключение. Перед выполнением арифметической операции один или оба операнда автоматически приводятся к одному типу, а затем уже подставляются в выражение. Значение любого выражения всегда имеет определенный тип - такой же, как у операндов после приведения их к одному типу. Правила преобразования целочисленных типов приведены в таблице 2.
Правила преобразования типов
Таблица 2
Операнды
Byte
ShortInt
Word
Integer
LongInt
Byte ShortInt
Word
Integer LongInt
Integer
Integer Word
Integer LongInt
Integer
Integer LongInt
Integer LongInt
Word LongInt
Word LongInt LongInt
Integer
Integer LongInt
Integer LongInt
LongInt
LongInt
LongInt LongInt LongInt
Если один операнд выражения имеет целочисленный тип, а второй - вещественный, то первый автоматически приводится к вещественному типу и значение выражения будет вещественным. Целые значения можно присваивать вещественной переменной, но вещественные значения присвоить целой переменной нельзя! Присваивая значение целочисленной переменной и константе, вы должны следить, чтобы это значение не выходило за пределы диапазона допустимых значений переменной. В языке Object Pascal есть возможность явно преобразовать целочисленное значение к любому из целочисленных типов, для этого используются стандартные функции с именами Byte, ShortInt, Word, Integerи LongInt. Например, преобразуем переменную типа Wordк типу Integer:
var x : word;
begin
x:=300;writeln(x,' ',integer(x));
x:=65535;writeln(x,' ',integer(x));
end.
Программа выведет:
300 300
65535 -1
В первом случае преобразование происходит корректно, а во втором - с изменением значения.
Арифметическое выражение может содержать любое количество операндов и, соответственно, любое количество операций, которые выполняются в последовательности, определенной их приоритетом; приоритет операций *, /, DIV, MODвыше, чем операций +и -. Операции одного приоритета выполняются слева направо. Чтобы изменить порядок выполнения операций, вы можете использовать в выражении круглые скобки. Вычислим, например, частное от деления Xна сумму A,B и C: X/(A+B+C);
Набор встроенных математических функций в языке Object Pascal невелик, он включает :
1. Abs(x) - абсолютная величина числа.
2. Int(x) - целая часть вещественного числа.
3. Frac(x) - дробная часть вещественного числа.
4. Trunc(x) - целая часть вещественного числа, преобразованная к типу LongInt.
5. Round(x) - округленное до целого вещественное число, преобразованное к типу LongInt.
6. Sqr(x) - квадрат числа.
7. Sqrt(x) - квадратный корень.
8. Exp(x) - экспонента.
9. Ln(x) - натуральный логарифм.
10. Pi- число пи.
11. Sin(x) - синус.
12. Cos(x) - косинус.
13. Arctan(x) - арктангенс.
Все остальные математические функции можно получить, пользуясь этим основным набором; например: десятичный логарифм - Ln(x)/Ln(10), тангенс -Sin(x)/Cos(x) и т.д. Аргументы функций могут быть любыми арифметическими выражениями и задаются в круглых скобках после имени функции, аргументы функций Sinи Cosвыражаются в радианах. Вычислим квадрат синуса 70 градусов: Sqr(Sin(Pi/180*70))
Кроме перечисленных выше математических функций Object Pascal предоставляет еще несколько полезных числовых функций и процедур разного назначения:
14. High(целый тип) - возвращает наибольшее возможное значение данного типа.
15. Low(целый тип) - возвращает наименьшее возможное значение данного типа.
16. SizeOf(тип)
SizeOf(переменная) - возвращает размер в байтах заданного типа или заданной переменной. Функция SizeOfприменима к любому типу, в том числе и к структурированным типам - массивам, записям и некоторым другим, речь о которых пойдет ниже.
17. Random(Range:Word) - возвращает целое случайное число в диапазоне от 0 до Range-1.
18. Random- возвращает вещественное случайное число в из отрезка [0, 1].
19. Randomize- процедура, инициализирующая генератор случайных чисел, используя текущее системное время
Выведем несколько случайных чисел в диапазоне от 0 до 99:
begin
randomize;
writeln(random(100));
writeln(random(100));
writeln(random(100));
end.
При первом запуске программы она вывела числа 13, 38, 48, при втором запуске - 63, 99, 6, при третьем запуске - 23, 87, 92. Это действие процедуры Randomize - поскольку при каждом запуске системное время, которое отсчитывает операционная система, было различным, мы каждый раз получали различные последовательности случайных чисел. Теперь исключим из программы оператор Randomize;и запустим ее несколько раз - каждый раз мы будем получать тройку чисел 0, 3, 86.
Обратите внимание, что процедура используется в операторе вызова, а функция используется в выражении. Запись Random(100);неверна, поскольку Random- это функция, но также неверна и запись WRITELN(Randomize);. Можно считать, что различие между процедурой и функцией состоит в том, что процедура выполняет некоторую последовательность действий, а функция вычисляет некоторое значение. Заметим, что READи WRITE- это тоже процедуры.
Для работы с внутренним двоичным представлением двухбайтовых целых чисел (типа Wordили Integer) существуют функции:
20. Lo(x) - возвращает младший байт аргумента.
21. Hi(x) - возвращает старший байт аргумента.
22. Swap(x) - меняет местами младший и старший байты.
Сделаем отступление о двоичной системе счисления. Все данные в памяти компьютера хранятся закодированными в двоичной системе. Любая переменная занимает целое число байтов, а каждый байт есть последовательность из 8 двоичных цифр - битов. Например, значение переменной типа Byte, равное 11, хранится как последовательность битов 0000 1011, а если переменная имеет тип Word, то ее значение кодируется как 0000 0000 0000 1101. 1024байта (или 2 в 10-й степени) имеют свое название - 1Кбайт, иногда эту величину также называют килобайт; 1024 Кбайт называют мегабайт. Пусть переменная tтипа Wordимеет значение 40000, или 1001 1100 0100 0000в двоичной системе, тогда функция Lo(t)возвратит 64( = 0100 0000), функция Hi(t)возвратит 156(= 1001 1100) и функция Swap(t)возвратит 16540( = 0100 0000 1001 1100).
Для целочисленных переменных определены процедуры:
23. Inc(x) Inc(x,d)
24. Dec(x) Dec(x,d).
Здесь x - имя переменной, d - любое целочисленное выражение. Процедура Incувеличивает значение переменной на d, а процедура Dec- уменьшает на d; второй аргумент этих процедур можно не задавать, тогда он будет принят равным 1. Например, вместо операторов a:=a+3; b:=b-1; c:=c+a+b; мы могли бы написать Inc(a,3); Dec(b); Inc(c,a+b); , и такой способ записи был бы предпочтительней.

7. Пример выполнения задания
Задача. Вычислить при х = 2.1; у = 0.59; z = -4.8 значения a и b, используя формулы:
; .
Вывести результаты, сопровождая их вывод именами выводимых переменных. Задание выпол­нить в виде консольного приложения. Повторить задание 1, используя функции из модуля math
Блок-схема алгоритма имеет вид:


Создадим простое консольное приложение. Для этого запустим Delphi и выполним ряд действий. Выберем команду FileNewOther (Файл Новый Другое), выделим пиктограмму Console Appli­cation (Консольное приложение) и щелкнем на кнопке ОК. При этом на экране появляется окно редактора кода, в котором введем следующий текст:
program Project1;
{$APPTYPE CONSOLE}
uses SysUtils;
var a,b,c,x,y,z: single;
proba:integer;
function Rus(mes: string):string;
var i: integer;
begin
for i:=1 to length(mes) do
case mes[i] of
'А'..'п' : mes[i] := Chr(Ord(mes[i]) - 64);
'р'..'я' : mes[i] := Chr(Ord(mes[i]) - 16);
end;
rus := mes;
end; { Rus }
begin { program }
writeln(Rus('Введите x, y, z'));
readln (x,y,z);
c:=sin(x*x)/cos(x*x);
a:=y*c*sqr(c)+sqrt(z*z/(y*y+x*x));
b:=ln(y+x*x)+sqr(sin(z/y));
writeln('a=',a:8:3,' b=',b:8:3);
readln;
end. { program}
Сохраним программу, выбрав последовательно команды FileSave Project As… Нажав клавишу <F9>, выполните программу. При этом на экране появляется такое ок­но работающего приложения.

Перейдем к следующему заданию. В листинг добавляем ссылку на модуль math, что позволяет использовать прямо функцию tan(аргумент) и функцию возведения в степень роwеr(основание, степень).
program Project1;
{$APPTYPE CONSOLE}
uses SysUtils, math;
var a,b,c,x,y,z: single;
proba:integer;
function Rus(mes: string):string;
var i: integer;
begin
for i:=1 to length(mes) do
case mes[i] of
'А'..'п' : mes[i] := Chr(Ord(mes[i]) - 64);
'р'..'я' : mes[i] := Chr(Ord(mes[i]) - 16);
end;
rus := mes;
end; { Rus }
begin { program }
writeln(Rus('Введите x, y, z'));
readln (x,y,z);
c:=tan(x*x);
a:=y*power(c,3)+sqrt(z*z/(y*y+x*x));
b:=ln(y+x*x)+sqr(sin(z/y));
writeln('a=',a:8:3,' b=',b:8:3);
readln;
end. { program}

8. Символьный тип данных

Для хранения символьной информации в Паскале предусмотрен специальный тип данных Char. Допустимы переменные, нетипизированные и типизированные константы такого типа. Данные типа Charзанимают 1 байт памяти. Неименованные символьные константы записываются в программе либо в виде 'символ', либо в виде #номер. Все имеющиеся символы пронумерованы от 0до 255, символы с 0-го по 31-й - невидимые, как правило, они не отображаются на экране, 32-й символ - это пробел.
Некоторые из невидимых символов могут оказаться полезны: символ #8– клавиша BackSpace; символ #10- "конец строки", при выводе он перемещает текущую позицию вывода на одну строку вниз; символ #13-"возврат каретки" - перемещает текущую позицию вывода в начало текущей строки. Клавиша Enterгенерирует два символа - #10и #13.
Символьные данные можно вводить и выводить процедурами READи WRITEпри вводе и выводе символьные значения изображаются без апострофов. Для символьных величин определены функции:
25. Ord(c) - возвращает номер символа.
26. Pred(c) - возвращает символ с номером, меньшим на 1.
27. Succ(c) - возвращает символ с номером, большим на 1.
Эти функции определены не только для символов, но для любого порядкового типа данных. Порядковым типом называется такой тип, все допустимые значения которого можно пронумеровать от 0 до некоторого N (в математике к этому понятию близко понятие счетного множества). Из известных нам типов порядковыми являются все целочисленные типы: Byte, ShortInt, Word, Integer, LongInt. И не являются порядковыми все вещественные типы. Значение функции Ordот числового аргумента равно самому этому аргументу, Pred(x) дает значение x-1, а Succ(x) - значение x+1. Функция
28. Chr(n) - в некотором смысле обратная функции Ord: для заданного числового аргумента n она возвращает символ с соответствующим номером. Для символьных переменных (так же, как и для любых переменных порядкового типа) определены процедуры Incи Dec. Еще одна специфически символьная функция:
29. UpCase(c) - преобразует значение аргумента, если это маленькая латинская буква, в соответствующую заглавную букву. К сожалению, функция не работает для русских букв.
Напишем простую программу, обрабатывающую символьные величины.
var c : char; n : byte;
const space =' ';
begin write('введите какой-нибудь символ '); read(c);
writeln('вы ввели символ',space,c,space,'его номер=',ord(c)); writeln('соседние с ним символы :',space,pred(c),space,
'и',space,succ(c));
writeln('upcase(',c,')=',upcase(c));
writeln;
write('теперь введите число от 33 до 255 '); read(n); writeln('символ с номером ',n,' - это ',space,chr(n),space); writeln;
readln
end.

9. Логический тип данных. Операции сравнения. Логические операции. Битовые операции

Логические, или булевские, данные предназначены для хранения логических значений "истина" или "ложь". Логические переменные и константы имеют тип Booleanи занимают в памяти 1 байт. Существует всего две логические константы - TRUEи FALSE, истина и ложь. Тип Boolean- это порядковый тип, поэтому для него определены функции Ord, Pred, Succи процедуры Incи Dec, причем Ord(FALSE)=0, Ord(TRUE)=1. Прежде чем перейти к логическим операциям, рассмотрим операции сравнения, которых в Паскале существует шесть:
=равно;
<>не равно;
<меньше;
<=меньше или равно;
>больше;
>=больше или равно.
Операции сравнения определены для любых однотипных операндов (числовых, символьных, логических); для числовых данных, так же, как и в случае арифметических операций, сделано исключение - вы можете сравнивать два числовых выражения любых типов, но сравнивать число и символ, число и логическую величину, символ и логическую величину нельзя! Результат операции сравнения есть TRUEили FALSE, в зависимости от того, выполнено или не выполнено условие. Числа сравниваются между собой естественным образом, символы - в соответствии с их номерами, а для логических величин справедливо неравенство FALSE<TRUE. Логических, или булевских, операций в Паскале четыре:
NOT- логическое отрицание;
AND- логическое "и";
OR- логическое "или";
XOR- логическое исключающее "или".
Правила выполнения этих операций таковы :
NOT- унарная (т.е. применимая к одному операнду) операция:
NOT FALSE= TRUE, NOT TRUE= FALSE.
Правила выполнения бинарных операций AND, ORи XORприведены в таблице 3.
Правила выполнения бинарных операцийТаблица 3
Операнд
Результат операции
a
b
a AND b
a OR b
a XOR b
false
false
true
true
false
true
false
true
false
false
false
true
false
true
true
true
false
true
true
false
Приоритет операции NOT(как и всякой унарной операции) наивысший, следующий приоритет у операции AND, и самый низкий приоритет - у операций ORи XOR. Выражения могут содержать не только разные логические операции, но и операции сравнения и арифметические, поэтому отметим, что приоритет логических и арифметических операций выше, чем операций сравнения. Существует функция, определенная для целочисленных аргументов и имеющая логическое значение, - это функция
30. Odd(x). Она возвращает TRUE, если значение x нечетное, и FALSE, если оно четное.
Логические значения можно выводить процедурой WRITE, но вводить логические переменные процедурой READнельзя. Теперь попробуем записать программу, использующую логические данные.
var a,b,c,d : integer;
begin writeln('введите 4 целых числа, a,b,c и d, среди ',
'которых должно быть 2 и только 2 одинаковых!'); write('a='); read(a); writeln;
write('b='); read(b); writeln;
write('c='); read(c); writeln;
write('d='); read(d); writeln;
writeln('вашу понятливость можно оценить как ',
(a=b)and(a<>c)and(a<>d)and(c<>d)or
(a=c)and(a<>b)and(a<>d)and(b<>d)or
(a=d)and(a<>b)and(a<>c)and(b<>c)or
(b=c)and(b<>a)and(b<>d)and(a<>d)or
(b=d)and(b<>a)and(b<>c)and(a<>c)or
(c=d)and(c<>a)and(c<>b)and(a<>b));
readln;
end.
Программа выведет TRUE, если введенные данные удовлетворили условию, и FALSE- в противном случае.
10. Условный оператор. Блок. Оператор выбора

Условный оператор в Паскале записывается в виде:
IFлогическое выражение
THENоператор/блок
[ELSEоператор/блок]
логическое выражение - это любое выражение, значение которого имеет тип Boolean, блок - это последовательность операторов, заключенная в логические скобки: BEGINоператоры END;. В условном операторе перед ELSEникогда не ставится ";" ! Перед ENDв большинстве случаев можно не ставить ";". Если значение логического выражения TRUE, то выполняется оператор или блок, стоящий после THEN, в противном случае - оператор или блок, стоящий после ELSE. Конструкция ELSEнеобязательна, условный оператор можно использовать и в усеченном виде, тогда при значении логического выражения FALSEне выполняется никаких действий. Операторы, входящие в условный оператор, сами могут быть условными, т.е. допускается любая вложенность условных операторов. Запишем теперь предыдущую задачу о четырех числах, используя оператор IF:
var a,b,c,d : integer;
begin writeln('Введите 4 целых числа, a,b,c и d, среди ',
'которых должно быть 2 и только 2 одинаковых!');
write('a='); read(a); writeln; write('b='); read(b); writeln;
write('c='); read(c); writeln; write('d='); read(d); writeln;
if (a=b)and(a<>c)and(a<>d)and(c<>d)
or(a=c)and(a<>b)and(a<>d)and(b<>d)or
(a=d)and(a<>b)and(a<>c)and(b<>c)or
(b=c)and(b<>a)and(b<>d)and(a<>d)or
(b=d)and(b<>a)and(b<>c)and(a<>c)or
(c=d)and(c<>a)and(c<>b)and(a<>b)
then
writeln('вы довольно понятливы')
else
writeln('вы ошиблись !!!');
readln;
end.
Можно решить эту задачу и другим способом :
var a,b,c,d : integer;
const num : byte = 0;
begin writeln('введите 4 целых числа, a,b,c и d, среди ',
'которых должно быть 2 и только 2 одинаковых!');
write('a='); read(a); writeln; write('b='); read(b); writeln;
write('c='); read(c); writeln; write('d='); read(d); writeln;
if a=b then inc(num);
if a=c then inc(num);
if a=d then inc(num);
if b=c then inc(num);
if b=d then inc(num);
if c=d then inc(num);
if num=1
then writeln('вы довольно понятливы')
else writeln('вы ошиблись !!!');
readln;
end.
Теперь попробуем записать условный оператор, реализующий более сложную логическую структуру. Пусть даны три числа d, mи y, содержащие число, месяц и год для некоторой даты; необходимо выяснить, правильна ли эта дата.
var d,m : byte;
y : word;
valid : boolean;
begin write('введите дату '); read(d,m,y);
if (m=1)or(m=3)or(m=5)or(m=7)
or(m=8)or(m=10)or(m=12)
then
if (d>=1)and(d<=31)
then valid:=true
else valid:=false
else
if (m=4)or(m=6)or(m=9)or(m=11)
then
if (d>=1)and(d<=30)
then valid:=true
else valid:=false
else
if m=2
then
if (d>=1)and(d<=28)
then valid:=true
else
if d=29
then
if (y mod 4=0)and
(y mod 100>0) or
(y mod 400=0)
then valid:=true
else valid:=false
else valid:=false
else valid:=false;
if valid
then writeln('дата верна')
else writeln('дата неверна');
end.
Оператор выбора во многих случаях удобнее, чем условный оператор, он записывается в виде:

CASEвыражение OF

..................................
список значений :оператор/блок
[;ELSEоператор/блок]


FORпеременная:=начальное значение TOконечное значение DO

оператор/блок
или

FORпеременная:=начальное значение DOWNTOконечное значение DO

Здесь переменная - любая переменная порядкового типа, называемая в таком контексте переменной цикла, начальное значение и конечное значение -… var i : word; s:single;
const n = 22;


STRING

или
STRING [максимальная длина ]
Если максимальная длина не задана, то по умолчанию она берется равной 255. Максимальная длина при описании строковых данных задается целочисленным константным выражением и никогда не может превышать 255. Это ограничение обусловлено самой структурой типа STRING: фактически строка - это массив ARRAY [Byte] OF Char, причем в 0-м символе закодирована текущая длина строки. Строковые переменные могут иметь любую длину от 0 до максимальной. В программе строки можно использовать и как единый структурированный объект (чуть позже мы познакомимся с разнообразными возможностями обработки строк), и как массив символов, т.е. обращаться к элементам строк следует так же, как к элементам массивов. Для строк определены следующие операции:
- строке можно присвоить строку;
- строки можно вводить процедурой READLN;
- строки можно выводить процедурой WRITE[LN];
- для строк определена операция конкатенации +, при этом вторая строка дописывается справа к первой и длина результата становится равной сумме длин операндов (если она не превосходит 255).
Запишем программу, выполняющую простейшие операции со строками:
type ShortString = string[80];
var s1,s2 : ShortString;
s,s3 : string;
begin
writeln(Rus('Введите 1-ю строку ')); readln(s1);
writeln(Rus(' Введите 2- ю строку ')); readln(s2);
writeln(Rus('Вы ввели '),s1,' & ',s2);
writeln(Rus('s1+s2='),s1+s2);
s3:=s1+s1+s1;
writeln(Rus('Строка s1,повторенная 3 раза '),s3); readln
end.
Обратите внимание, что при вводе строк всегда используется READLN, но не READ. Процедура READв отличие от READLNсчитывает лишь символы до символа конца строки (клавиша Enter), который остается в буфере клавиатуры. Таким образом, пользуясь процедурой READможно ввести только одну строку; все строки, вводимые вслед за первой, станут пустыми. Запишем теперь программу, которая вводит некоторую строку, заменяет в ней все цифры на пробелы и дописывает в конец строки символы "???":
var s : string;
l,i : byte;
begin write('введите строку '); readln(s);
l:=ord(s[0]);
for i:=1 to l do if s[i] in ['0'..'9'] then s[i]:=' ';
for i:=l+1 to l+3 do s[i]:='?';
writeln(Rus( 'вот что получилось : '),s); readln
end.
Наша программа заменила цифры, но никаких трех знаков вопроса не добавила. Дело в том, что, обращаясь к элементам строки, невозможно изменить текущую длину строки. Второй цикл нашей программы сработал правильно, записав символы "?" в соответствующие элементы строки, но длина строки осталась прежней, и процедура WRITELNвывела только символы с 1-го по L-й. Чтобы решить задачу корректно, мы могли бы добавить в программу один оператор INC(s[0],3); но, конечно, лучше всего просто записать: s:=s+'???';
Для обработки строк в Паскале существует несколько стандартных функций и процедур :
1. FUNCTION Length(S: String): Integer; - возвращает длину строки.
2. FUNCTION Concat(S1[,S2,...,Sn]: String): String; - возвращает строку, полученную сцеплением аргументов S1[,S2,...,Sn], может использоваться вместо операции "+".
3. FUNCTION Pos(Substr: String; S: String): Byte; - возвращает номер первого слева символа строки S, начиная с которого строка Substr входит в S, если Substr не входит в S, то значение функции равно 0.
4. FUNCTION Copy(S: String; Index: Integer; Count: Integer): String; - возвращает подстроку строки S, которая начинается с символа с номером Index и имеет длину Count.
5. PROCEDURE Delete(VARS: String; Index: Integer; Count:Integer); - удаляет из строки S подстроку, начинающуюся с символа с номером Index и имеющую длину Count.
6. PROCEDURE Insert(Substr: String; VARS: String; Index: Integer); -вставляет в строку S подстроку Substr начиная с символа с номером Index.
Еще две стандартные процедуры предназначены для перевода строки в число и числа в строку:
7. PROCEDURE Val(S: STRING;VARV; VARCode: Integer); - преобразует строку S в число V (если это возможно); V - любая переменная арифметического типа, переменная Code возвращает 0, если преобразование прошло успешно, или номер первого неправильного символа строки.
8. PROCEDURE Str(X [:Width [:Decimals ]];VARS:STRING); - преобразует произвольное арифметическое выражение X в строку S, параметры Width и Decimals позволяют форматировать строку и имеют такой же смысл, как и в процедуре WRITE[LN] .
Теперь, зная процедуру Val, вы можете организовать надежный ввод числовых данных в любой своей программе. Предположим, что программа должна вводить вещественное значение F. Мы можем записать это так:
var f : single; ...
begin write('введите f '); read(f); …
Если пользователь правильно введет число, то все будет в порядке, но если он ошибочно или преднамеренно нажмет не ту клавишу (например, запятую вместо точки и т.п.), то произойдет аварийное прерывание программы. Программы, таким образом, реагирующие на неверный ввод, нельзя назвать хорошими. Хорошая программа обязана обрабатывать нажатие практически любых клавиш в любых комбинациях. Мы можем предложить следующий вариант:
var f : single;
s : string;
code : integer; ...
begin repeat
write('введите f '); readln(s);
val(s,f,code);
if code=0 then break;
writeln('ошибка ввода!');
until false;
Решим часто встречающуюся задачу о распаковке текста: дана строка, содержащая текст на английском языке; нужно выделить слова, содержащиеся в этом тексте. Хотя эта задача и элементарна, ее решение не столь тривиально и требует предварительной разработки алгоритма. Сначала уясним, что такое текст. Текстом будем называть последовательность слов, разделенных любым количеством "разделителей". Слова - это последовательности букв языка (в нашем случае - английских букв), "разделители" - любые символы, не являющиеся буквами. Итак, наш текст в общем случае имеет вид : *X*X...*X*,где X- слово, *- "разделитель". Можно предложить следующий алгоритм распаковки:
1) удалим завершающие пробелы, после чего текст примет регулярный вид *X*X...*X*;
2) удалим лидирующие пробелы;
3) выделим первое слово и удалим его из текста.
После выполнения пунктов 2 и 3 мы получили одно слово и текст стал короче на одно слово, сохранив при этом свою структуру. Очевидно, что пункты 2 и 3 следует выполнять до тех пор, пока текст не пуст. Запишем программу, реализующую этот алгоритм.
var s : string;
i : byte;
const letters : set of char = ['a'..'z','A'..'Z'];
begin writeln(Rus('введите текст ')); readln(s);

{ удалим завершающие пробелы, здесь есть 1 ошибка! }
while not(s[length(s)] in letters) do
delete(s,length(s),1);
writeln(Rus('слова текста :'));
{ организуем цикл по словам }
while s<>'' do
begin
{ удалим лидирующие пробелы }
while not(s[1] in letters) do delete(s,1,1);

{ найдем границу первого слова, здесь есть 1 ошибка! } i:=1;
while s[i] in letters do inc(i); { i - номер первого пробела } dec(i);
writeln(copy(s,1,i)); { выведем слово }
delete(s,1,i); { удалим слово из текста }
end;
readln
end.
На первый взгляд наша программа работает правильно (мы ввели текст латиницей и получили все слова из него), но тестирование программы обязательно должно включать все предельные, или особенные, случаи. Введем, например, строку, не содержащую никаких слов, и программа сработает неправильно: она либо зациклится, либо пользователь не получит никакого сообщения - все завершится просто сворачиванием окна вывода. Это результат ошибки в первом цикле: если в тексте нет букв, все символы из него будут удалены, длина строки станет равной нулю, и в дальнейшем станет проверяться символ с номером 0, который равен #0и, естественно, не является буквой. Еще одна ошибка подобного рода может произойти при выделении последнего слова: мы увеличиваем индекс i, пока i-й символ - буква, и, в конце концов, дойдем до конца строки. Но переменная sвсегда содержит 255 символов, символы с номерами Length(s)+1, Length(s)+2и т.д. существуют, и нет никаких гарантий, что они не являются английскими буквами. В этом случае мы можем получить последнее слово с "хвостом". Исправим нашу программу:
var s : string; i : Byte;
const Letters : set of Char = ['a'..'z','A'..'Z'];

begin
writeln(Rus('Введите текст латиницей')); readln(s);
while not(s[Length(s)] in Letters)and(s<>'') do
Delete(s,Length(s),1);
if s=''
then
begin
writeln(Rus('текст не введен'));
Halt;
end;
writeln(Rus('Слова текста :'));
while s<>'' do {цикл выделения отдельных слов}
begin
while not(s[1] in Letters) do
Delete(s,1,1);
i:=1;
while (s[i] in Letters) and (i<=Length(s)) do
inc(i);
Dec(i);
writeln(Copy(s,1,i));
Delete(s,1,i);
end;
readln;
end.
Теперь запишем то же самое, используя функции и процедуры :
var s : string;
i : byte;
const letters : set of char = ['a'..'z','A'..'Z'];

{процедура удаления завершающих пробелов}
procedure del_tail(var s:string);
begin
while not(s[length(s)] in letters)and(s<>'') do
delete(s,length(s),1);
end; {del_tail}

{процедура удаления лидирующих пробелов}
procedure del_head(var s:string);
begin
while not(s[1] in letters) do
delete(s,1,1);
end; {del_head}

{функция выделения отдельного слова}
function makeword(s:string; var bound:byte):string;
begin bound:=1;
while (s[bound] in letters)and(bound<=length(s)) do
inc(bound);
dec(bound);
makeword:=copy(s,1,i);
end; {makeword}

begin writeln(Rus('введите текст ')); readln(s);
del_tail(s);
if s='' then
begin writeln(Rus('текст не введен'));
halt;
end;
writeln(Rus('слова текста :'));

while s<>'' do { организуем цикл по словам }
begin
del_head(s);
writeln(makeword(s,i));
delete(s,1,i);{ удаление слова из текста }
end; readln
end.

18. Погрешности при вычислениях

В отличие от целочисленных выражений, которые всегда вычисляются точно, вещественные выражения дают приближенный результат, и вещественные переменные содержат приближенные значения. Например, выполним программу
var x : single;
begin x:=1/3;
writeln(x*3-1 :15:10); readln
end.
Мы получим не 0 (точное значение выводимого выражения), а, например, 0.0000000298, а может быть, какое-нибудь другое маленькое число. Это обусловлено тем, что переменные типа Singleхранят конечное число десятичных цифр (11-12 цифр), кроме того, эти цифры хранятся в двоичном коде, поэтому мы и не получили 1E-12или 1E-13. Таким образом, x/a*aдалеко не всегда равно x. И наоборот, a+xможет быть равно a, даже если xне равно нулю. Найдем такое положительное число, которое удовлетворяет уравнению x+1=1:
const x:single;
begin x:=1;
while x+1<>1 do
x:=x/2;
writeln(x); readln
end.
Мы получим, например, 5.42E-20(результат зависит от типа компьютера).
Решим реальную задачу, в которой используются приближенные вычисления: вычислить сумму ряда . Несмотря на то, что необходимо просуммировать бесконечное число слагаемых, эта задача легко решается за конечное время, так как общий член ряда быстро убывает и, начиная с некоторого n,прибавление очередного слагаемого уже не будет изменять сумму. Сначала напишем плохую программу:
function factorial(n:word):single;
var i:word; f:single;
begin f:=1;
for i:=1 to n do f:=f*i;
factorial:=f;
end; { factorial }

function power(x:single; n:word):single;
var i:word; f:single;
begin if n=0
then power:=1
else begin f:=x;
for i:=2 to n do f:=f*x;
power:=f;
end;
end;{ power}

var x,s1,s2 : single;
i : word;
begin writeln('введите x '); readln(x);
s2:=0; i:=0;
repeat
s1:=s2;
s2:=s1+power(x,i)/factorial(i);
inc(i);
until s1=s2;
writeln('сумма ряда = ',s1); readln
end.
Запустим эту программу, задав x=1; мы получим верный результат 2.71828... (его легко проверить, поскольку сумма нашего ряда равна exp(x)). А теперь попытаемся поочередно запускать программу для x=10, 11, 12, 13… И для какого-то х результат получен не будет. В данном случае это переполнение, оно происходит всякий раз, когда вещественная величина превышает максимально допустимое значение 1.7E38. Следовательно, для некоторого iмы уже не можем вычислить i!.
Означает ли это, что решить задачу невозможно? Вовсе нет; конечно, мы не можем задать нашей программе очень большое значение x, но значение 10вполне приемлемо, дело здесь в качестве нашей программы. Действительно, посмотрим, как работает программа: для вычисляется x0 и 0!, затем для i=1 заново вычисляется x1 и 1! и т.д. до получения результата; но xi+1=xxi и (i+1)!=(i+1)i!, так что, зная предыдущие значения, достаточно выполнить всего одну операцию, чтобы получить последующие. Более того, нам вовсе не нужен факториал сам по себе, а только общий член ряда (в котором этот факториал находится в знаменателе). Нетрудно записать рекуррентную формулу для общего члена ряда: , , откуда .Кроме того, что таким образом мы избавимся от переполнения, пользуясь этой формулой, мы еще и увеличим скорость нашей программы.
var x,s1,s2,a : single;
i : word;
begin i:=0;
writeln(Rus('введите x )'); readln(x);
a:=1; s2:=0;
repeat s1:=s2;
s2:=s1+a;
inc(i);
a:=a*x/i;
until s1=s2;
writeln(Rus('сумма ряда = '),s1); readln
end.
Программа сработала для x=10и x=20и x=50, но для x=100снова произошло переполнение. Но здесь уже ничего сделать нельзя, exp(100)>1043 и никак не может быть представлена вещественным значением типа Single.
Решим еще одну задачу: найти корень уравнения f(x)=0методом бисекции или половинного деления. Метод бисекции заключается в следующем: пусть уравнение имеет единственный корень на отрезке [a,b] - это значит, что график функции один раз пересекает ось абсциссна этом отрезке. Определим знак функции в точке a и в точке x=(a+b)/2. Если эти знаки одинаковы, то корень лежит на отрезке [x,b], в противном случае - на отрезке [a,x]. Таким образом, за один шаг метода мы ровно вдвое уменьшили наш отрезок; будем повторять эти операции до тех пор, пока отрезок не станет очень маленьким, и в качестве корня возьмем середину этого маленького отрезка. Попробуем реализовать этот метод:
var a, b, epsilon, x, fa, fx: single;
function f(x:single):single;
begin f:=exp(x)-2;
end; {f}

begin epsilon:=1e-10; a:=0; b:=10;
fa:=f(a);
while b-a>epsilon do
begin x:=(a+b)/2;
fx:=f(x);
if fx=0
then begin writeln(x);
halt;
end;
if fa*fx<0
then b:=x
else a:=x;
end;
writeln(Rus('Корень уравнения Exp(x)=2 на отрезке от 0 до 10 равен '),x:10:8);
writeln(Rus('Значение функции в этой точке = '),f(x):10:8);
readln
end.
В результате выполнения программы получим корень х= 0.69314003. Теперь найдем пробелы в программе. Для этого вычислим корень уравнения ln(x)-50=0, a=1, b=1e30 - программа зациклится! Выведем внутри цикла значения aи b: эти числа почти одинаковы и не меняются, но поскольку их порядок 1021, b-aсущественно превосходит наш отрезок. Есть два способа, которыми мы можем исправить положение. Первый заключается в правильном подборе отрезка, но надо понимать, что придется подбирать этот отрезок для каждого нового уравнения, то есть фактически для каждого уравнения писать свою программу. Очевидно, что это бесперспективный путь. Выведем в нашей зацикленной программе не только aи b, но и x, может быть, это поможет нам придумать второй способ: значение x, оказывается, в точности равно b.
Мы могли бы прийти к выводу, что рано или поздно xстанет равным или aили b, рассуждая чисто теоретически. Действительно, на каждом шаге цикла мы уменьшаем отрезок в два раза; если бы мы работали на вещественной оси, то величины aи bстремились бы друг к другу бесконечно, но, поскольку множество вещественных чисел в компьютере дискретно (из-за конечного числа цифр), настанет момент, когда между aи bбольше не будет ни одного числа. После этого выражение (a+b)/2будет давать либо a, либо b. Воспользуемся этим обстоятельством и напишем следующую программу:
var a, b, epsilon, x, fa, fx: single;
function f(x:single):single;
begin f:= Ln(x)-50;
end; {f}

begin a: = 1; b: = 1e30;
fa:=f(a); x:=(a+b)/2;
while (x<>a)and(x<>b) do
begin fx:=f(x);
if fx=0
then begin writeln(x);
halt;
end;
if fa*fx<0
then b:=x
else a:=x;
x:=(a+b)/2;
end;
writeln(x); readln
end.
Программа дала верный результат 5.184705...E21.
Решим еще одну задачу: вычислить значения функции f(x)=ln(1+ln(1+exp(exp(x)))) на отрезке [0,1000]с шагом 5.
var x0, x1, h, x : single;
var i : byte;
function f(x:single):single;
begin f:=ln(1+ln(1+exp(exp(x))));
end; {f}

begin x0:= 0; x1:= 1000; h:= 5;
for i:=0 to round((x1-x0)/h) do
begin
x:=x0+i*h;
writeln('x=',x:4:0,' f(x)=',f(x));
end;
end.
При x=10произошло переполнение. Означает ли это, что задача неразрешима? Нет, мы просто написали плохую программу, скопировав математическую формулу в оператор Паскаля. Посмотрим, в каком месте происходит переполнение - очевидно, при вычислении exp(exp(x)), других возможностей просто не существует. Это значит, что полученное значение exp(exp(x))превосходит 1E38. Посмотрим на аргумент внутреннего логарифма: прибавление единицы к очень большому числу никак не изменит это число, следовательно, этой единицей можно пренебречь. Таким образом, для x≥5наша формула упрощается:
f(x)=ln(1+ln(1+exp(exp(x))))=ln(1+ln(exp(exp(x))))=ln(1+exp(x))
Исправим программу:
function f(x:single):single;
begin if x<5
then f:=ln(1+ln(1+exp(exp(x))))
else f:=ln(1+exp(x));
end; {f}
Сделаем некоторые выводы из вышесказанного. Компьютерные вычисления несколько отличаются от абстрактных математических вычислений. В математике вещественная ось непрерывна (между двумя любыми вещественными числами находится бесконечное множество чисел) - компьютерное множество вещественных чисел дискретно. Математика оперирует с бесконечно большими и бесконечно малыми величинами - компьютерные вещественные числа ограничены сверху и снизу. Математические вычисления точны - компьютерные вычисления приближенны. Вы должны учитывать это, когда программируете какую-либо вычислительную задачу.

19. Файлы. Работа с текстовыми файлами

Научимся работать с внешними файлами: читать из них информацию, записывать информацию в файл, корректировать файлы, создавать новые файлы, переименовывать и уничтожать существующие файлы. Различают три типа файлов: текстовые, типизированные и бинарные. Это различие влияет лишь на способы обращения к файлу, один и тот же файл на диске программа может рассматривать и как текстовый, и как типизированный, и как бинарный. Рассмотрим текстовые файлы.
Для работы с текстовым файлом в программе следует описать файловую переменную типа TEXT:
VARf : TEXTFILE;
которая называется дескриптором файла. В дескрипторе хранится указатель файла, который похож на курсор в текстовом редакторе. Как и курсор, указатель файла обозначает текущую позицию в открытом текстовом файле. В режиме чтения информации из файла указатель файла определяет следующий элемент данных, который будет считан из файла. В режиме записи указатель файла определяет позицию, в которую будет записан следующий элемент данных.
Описав дескриптор файла, необходимо связать или инициализировать файл, т.е. установить связь файловой переменной с файлом на диске процедурой
1. AssignFile(VAR f:TEXT; Name:String),
где Name - правильно построенное имя файла, существующего или вновь создаваемого. Если файл находится не в текущей папке - в той, где хранится ваша программа, в Name должно быть указано полное имя файла, включая имя диска и всех папок.
После этого для доступа к файлу выполняется открытие файла одной из трех процедур:
2. Reset(VAR f:TEXT)- открывает файл для чтения.
3. Rewrite(VAR f:TEXT)- открывает файл для записи.
4. Append(VAR f:TEXT)- открывает файл для записи в конец файла. Процедуры Resetи Appendвыполняются только для существующих файлов, процедура Rewrite- для любых файлов, но если файл существует, он будет уничтожен и создан заново. Чтение из файла и запись в файл выполняются процедурами READ[LN]и WRITE[LN], но перед списком ввода или вывода задается файловая переменная:
5. Read[Ln](VAR f:TEXT; список ввода).
6. Write[Ln](VAR f:TEXT;список вывода).
Списки ввода и вывода строятся точно так же, как и в случае ввода с клавиатуры и вывода на экран. Особенностью текстовых файлов является то, что они состоят из строк, каждая из которых заканчивается символом конца строки. Процедура WriteLnзаписывает в файл этот символ, а процедура Write- нет. Вы можете сами управлять длинами записываемых строк, в нужный момент вызывая процедуру WriteLn. При вводе следует помнить, что если символ конца строки не считан процедурой ReadLn, то следующая строка недоступна. Как правило, текстовый файл используется для хранения строк или символов, но можно держать там и числа.
Для текстовых файлов определены четыре логические функции:
7. Function EOLN(VAR f:TEXT):Boolean- возвращает TRUE, если при чтении достигнут конец строки.
8. Function EOF(VAR f:TEXT):Boolean- возвращает TRUE, если при чтении достигнут конец файла.
9. Function SeekEOLN(VAR f:TEXT):Boolean- возвращает TRUE, если в строке больше нет ничего, кроме пробелов.
10. Function SeekEOF(VAR f:TEXT):Boolean- возвращает TRUE, если в файле нет больше ничего, кроме пробелов.
Функция EOLNпригодится вам, если вы читаете из текстового файла символы; функция EOF- если вы читаете символы или строки, а функции SeekEOLNи SeekEOFнеобходимы при вводе чисел из текстового файла. Функции EOLNи SeekEOLNтакже могут быть полезны при обычном вводе с клавиатуры. Приведем пример: пусть необходимо ввести некоторый массив натуральных чисел и некоторый массив символов. Известно, что в обоих массивах не более 100 элементов. Запишем программу, которой не нужно заранее знать, сколько элементов будет введено, это удобнее, чем сначала запрашивать количество элементов в массиве.
const nmax=100;
var x : array[1..nmax] of word;
c : array[1..nmax] of char;
i, nx, nc : byte;
begin
nx:=0; nc:=0;
writeln(Rus('введите числа'));
{вводим все числа, заканчивая клавишей enter}
while not seekeoln do
begin inc(nx);
read(x[nx]);
end;
{считываем конец строки, иначе не введутся символы}
readln;
{вводим символы, заканчивая клавишей enter}
writeln(Rus('введите символы')); while not eoln do
begin inc(nc);
read(c[nc]);
end;
writeln(Rus('введено '),nx,Rus(' чисел :'));
for i:=1 to nx do
write(x[i]:8);
writeln;
writeln(Rus('введено '),nc,Rus(' символов :'));
for i:=1 to nc do
write(c[i]);
writeln; readln;readln;
end.
Вернемся к работе с файлами. Файл закрывается процедурой.
11. Procedure Close(VARf:TEXT),
после чего файловую переменную можно использовать для других целей. Любой файл можно удалить с диска процедурой.
12. Procedure Erase(VARf).
Удаляемый файл должен быть инициализирован, но не открыт, или открыт, но затем закрыт. Напишем программу, которая читает текстовый файл и выводит его на экран. Для ее работы нам понадобится создать при помощи любого текстового редактора файл, сохранить его под именем test.txt в той же папке, где будет храниться наша программа:
var f : textfile;
s : string;
const name='test.txt';
begin
assign(f,name);
reset(f);
while not eof(f) do
begin readln(f,s);
writeln(s);
end;
close(f); readln
end.
Теперь выполним то же самое, не используя строку:
var f : text;
c : char;
const name='test.txt';
begin
assign(f,name);
reset(f);
while not eof(f) do
begin
while not eoln(f) do
begin read(f,c);
write(c);
end;
readln(f);
writeln;
end;
end.
Если в этой программе опустить READLN(f), то она зациклится. Прочтем из текстового файла числа (в таком файле должны быть записаны только числовые константы и пробелы):
var f : text;
x : single;
const name='num.txt';
begin
assign(f,name);
reset(f);
while not seekeof(f) do
begin read(f,x);
write(x:10:5);
end; readln
end.
Числа в текстовом файле могут быть записаны как в одной, так и в нескольких строках и разделяться любым количеством пробелов.


ЗАДАНИЯ ДЛЯ ЛАБОРАТОРНЫХ РАБОТ

Лабораторная работа №1. Вычисление простейших арифметических выражений
Даны два действительных числа и . Получить их сумму, разность и произведение. Даны действительные числа и .
Дана длина ребра куба. Найти объем куба и площадь его боковой поверхности. Даны два действительных положительных числа. Найти среднее арифметическое и среднее геометрическое этих чисел. Даны два действительных числа. Найти среднее арифметическое этих чисел и среднее геометрическое их модулей. Даны катеты прямоугольного треугольника. Найти его гипотенузу и площадь. Определить периметр правильного -угольника, описанного около окружности радиуса . Даны , , . Вычислить , , если , .
Даны , , . Вычислить , , если , .
Дана сторона равностороннего треугольника. Найти площадь этого треугольника. Даны гипотенуза и катет прямоугольного треугольника. Найти второй катет и радиус вписанной окружности. Известна длина окружности. Найти площадь круга, ограниченного этой окружностью. найти площадь кольца, внутренний радиус которого равен 20, а внешний – заданному числу (). Найти сумму членов арифметической прогрессии , , …,
по данным значениям , , .
Найти площадь равнобочной трапеции с основаниями и и углом при большем основании . Вычислить расстояние между двумя точками с координатами , и , . Дано действительное число . Не пользуясь никакими другими арифметическими операциями, кроме умножения, сложения и вычитания, вычислить .
Разрешается использовать не более четырех умножений и четырех сложений и вычитаний.
Дано действительное число . Не пользуясь никакими другими арифметическими операциями, кроме умножения, сложения и вычитания, вычислить и .
Разрешается использовать не более восьми операций.
Дано действительное число . Не пользуясь никакими другими арифметическими операциями, кроме умножения, получить за пять операции. Дано действительное число . Не пользуясь никакими другими арифметическими операциями, кроме умножения, получить и за пять операции. Лабораторная работа №2. Разветвления
Даны действительные числа , . Получить . Даны действительные числа , . Получить . Примечание. Здесь и далее обозначает минимальное из чисел x и y, – максимальное из чисел x и y.
Даны действительные числа , , . Получить . Даны действительные числа , , . Получить . Даны действительные числа , , . Вычислить . Даны действительные числа , , . Вычислить . Даны действительные числа , , . Проверить, выполняются ли неравенства . Даны действительные числа , , . Удвоить эти числа, если , и заменить их абсолютными значениями, если это не так. Даны действительные числа , . Вычислить :
Даны два действительных числа. Вывести первое число, если оно больше второго, и оба числа, если это не так. Даны два действительных числа. Заменить первое число нулем, если оно меньше или равно второму, и оставить числа без изменения в противном случае. Даны три действительных числа. Выбрать их них те, которые принадлежат интервалу . Даны действительные числа , (). Меньшее из этих двух чисел заменить их полусуммой, а большее – их удвоенным произведением. Даны три действительных числа. Возвести в квадрат те из них, значения которых неотрицательны. Если сумма трех попарно различных действительных чисел , , меньше единицы, то наименьшее из этих трех чисел заменить полусуммой двух других; в противном случае заменить меньшее из и полусуммой двух оставшихся значений. Даны действительные положительные числа , , . Выяснить, существует ли треугольник с длинами сторон , , . Даны действительные числа , , (). Выяснить, имеет ли уравнение действительные корни. Если действительные корни имеются, то найти их. В противном случае ответом должно служить сообщение, что действительных корней нет. Даны действительные числа , , , , , . Принадлежит ли начало координат треугольнику с вершинами , , ? Дано действительное число . Вычислить , если
Дано действительное число . Вычислить , если
Лабораторная работа №3. Простейшие циклы
Дано натуральное число . Вычислить . Дано натуральное число . Вычислить . Дано натуральное число . Вычислить .
Дано действительное число , натуральное число . Вычислить . Дано действительное число , натуральное число . Вычислить . Дано действительное число , натуральное число Вычислить .
Вычислить . Дано действительное число . Вычислить .
Дано натуральное , действительное . Вычислить . Дано натуральное число. Сколько цифр в числе ? Дано натуральное число. Чему равна сумма его цифр? Дано натуральное число. Найти первую цифру числа . Даны натуральные числа и . Получить сумму последних цифр числа . Дано натуральное число . Выяснить, входит ли цифра 3 в запись числа . Дано натуральное число . Поменять порядок цифр числа на обратный. Дано натуральное число . Переставить первую и последнюю цифры числа . Пусть ; ,
Дано натуральное число . Получить .
Алгоритм Евклида нахождения наибольшего общего делителя (НОД) неотрицательных целых чисел основан на следующих свойствах этой величины. Пусть и – одновременно не равные нулю целые неотрицательные числа и пусть . Тогда, если , то , а если , то для чисел , и , где – остаток от деления на , выполняется равенство . Например, . Даны натуральные числа , . Используя алгоритм Евклида, найти наибольший общий делитель и . Даны натуральные числа и . Найти такие натуральные и , не имеющие общих делителей, что . Даны натуральное число , действительное число . Вычислить . Лабораторная работа №4. Итерационные циклы. Вычисление суммы ряда
Для заданного положительного , описывается как константа, и заданного , вводится с клавиатуры, вычислить сумму ряда с точностью . Значение параметра , входящего в некоторые варианты, вводится с клавиатуры. Значение полученной суммы сравнить с соответствующим значением в левой части равенства. Так же на печать выдать количество суммируемых членов ряда. Предусмотреть ограничение количества слагаемых ряда для предотвращения «зацикливания». Приложением должен быть также предусмотрен ввод чисел только из указанного диапазона.
, . , . , . , . , , . , , . , , . , . , . , . ., . , . , . , . , . , . , . , . , . , . , . Лабораторная работа №5. Целые числа
Дано натуральное число . Получить все пифагоровы тройки натуральных чисел, каждое из которых не превосходит , т.е. все такие тройки натуральных чисел, что (). Треугольником Паскаля называется числовой
треугольник, в котором по краям стоят единицы, а каждое число внутри равно сумме двух стоящих над ним в ближайшей строке сверху. Дано натуральное . Получить первые строк треугольника Паскаля.
Дано натуральное число . Найти все меньшие числа Мерсена. Простое число называется числом Мерсена, если оно может быть представлено в виде , где – тоже простое число. Два натуральных числа называют дружественными, если каждое из них равно сумме всех делителей другого, кроме самого этого числа. Найти все пары дружественных чисел, лежащих в диапазоне от 200 до 300. Дано натуральное число . Среди чисел найти все такие, запись которых совпадает с последними цифрами записи их квадрата (как, например, , и т.д.). Натуральное число из цифр является числом Армстронга, если сумма его цифр, возведенная в -степень, равна самому числу (как, например, ). Получить все числа Армстронга, состоящие из двух, трех и четырех цифр. Назовем натуральное число палиндромом, если его запись читается с начала и с конца (как, например, 4884, 393, 1). Найти все меньшие 100 натуральные числа, которые при возведении в квадрат дают палиндром. Найти все меньшие 100 числа – палиндромы (см. предыдущую задачу), которые при возведении в квадрат также дают палиндромы. Найти все простые несократимые дроби, заключенные между 0 и 1, знаменатели которых не превышают 7 (дробь задается двумя натуральными числами – числителем и знаменателем). Дано натуральное число . Выяснить, можно ли представить в виде произведения трех последовательных целых чисел. Дано натуральное число . Получить в порядке возрастания первых натуральных чисел, которые не делятся ни на какие простые числа, кроме 2, 3 и 5. Дано натуральное число (). Получить все способы выплаты суммы с помощью монет достоинством 1, 2, 5 и 10 рублей. Дано натуральное число (). Получить все пятерки натуральных чисел , , , , такие, что и . Дано натуральное число . Каким наименьшим количеством монет можно выплатить рублей? Предполагается, что в достаточно большом количестве имеются монеты достоинством 1, 2, 5, 10 рублей. Даны натуральные числа . Предположим, что имеются 10 видов монет достоинством . Обозначим через число способов, которыми можно выплатить сумму , т.е. – это число решений уравнения , где может принимать целые неотрицательные значения. Получить . Даны натуральные числа . Предположим, что имеются 10 гирь весом . Обозначим через число способов, которыми можно составить вес , т.е. – это число решений уравнения , где может принимать значение 0 и 1 (). Получить . Рассмотрим некоторое натуральное число . Если это – не палиндром, то изменим порядок его цифр на обратный и сложим исходное число с получившимся. Если сумма – не палиндром, то над ней повторяется то же действие и т.д., пока не получится палиндром. До настоящего времени неизвестно, завершается ли этот процесс для любого натурального . Даны натуральные числа , , (). Проверить, верно ли, что для любого натурального числа из диапазона от до процесс завершится не позднее, чем после таких действий. Рассмотрим некоторое натуральное число (). Если оно четно, то разделим его на 2, иначе умножим на 3 и прибавим 1. Если полученное число не равно 1, то повторяется то же действие и т.д., пока не получится 1. До настоящего времени неизвестно, завершается ли этот процесс для любого натурального . Даны натуральные числа , , (). Проверить, верно ли, что для любого натурального числа из диапазона от до процесс завершится не позднее, чем после таких действий. Дано натуральное число . Получить , каждая цифра которого в сумме с соответствующей цифрой числа равна десяти. (Например, , ). Дано натуральное трехзначное число. Определить цифры этого числа (, , ) и выяснить, можно ли построить произвольный треугольник со сторонами , , . Лабораторная работа №6. Вычисления с хранением последовательностей
Даны действительные числа , …, . Получить числа , …, , где – среднее арифметическое всех членов последовательности , …, , кроме (). Даны действительные числа , …, , , …, . Получить . Как упростить решение, если исходные данные будут иметь следующий порядок: , , , , …, , ? Построить последовательность целых чисел , …, , где ; ; (). Даны натуральные числа , …, , действительные числа , …, . Вычислить . Даны действительные числа , …, , , …, . Вычислить . Даны целые числа , …, . Получить новую последовательность, выбросив из исходной все члены со значением . Даны действительные числа , …, . Если в результате замены отрицательных членов последовательности , …, их квадратами члены будут образовывать неубывающую последовательность, то получить сумму членов исходной последовательности; в противном случае получить их произведение. Даны целые числа , …, . Все члены последовательности с четными номерами, предшествующие первому по порядку члену со значением , домножить на . Дано натуральное число , действительные числа , …, (числа , …, попарно различны, ). В последовательности , …, поменять местами наибольший член и член с номером . Даны действительные числа , …, . Получить . Даны действительные числа , …, . Преобразовать эту последовательность по правилу: большее из и () принять в качестве нового значения , а меньшее – в качестве нового значения . Даны целые числа , …,. Если в данной последовательности ни одно четное число не расположено после нечетного, то получить все отрицательные члены последовательности, иначе – все положительные. Порядок следования чисел в обоих случаях заменяется на обратный. Даны целые числа , …,. Наименьший член последовательности , …,заменить целой частью среднего арифметического всех членов, остальные члены оставить без изменения. Если в последовательности несколько членов со значением , то заменить последний по порядку. Даны действительный числа , …,(все числа попарно различны). Поменять в этой последовательности местами наибольший и наименьший члены. Даны действительный числа , …,(все числа попарно различны). Поменять в этой последовательности местами наибольший и последний члены. Даны целые числа , …,. Получить новую последовательность из 100 целых чисел, заменяя нулями, если не равно , и заменяя единицей в противном случае (). Даны целые числа , …,, , …, . Преобразовать последовательность , …, по правилу: если , то увеличивается в 10 раз, иначе заменить нулем (). Даны действительные числа , …,. Требуется домножить все члены последовательности , …,на квадрат ее наименьшего члена, если , и на квадрат ее наибольшего члена, если . Дано натуральное число . Сколько различных цифр встречается в его десятичной записи? Даны действительные числа , …,. Оставить без изменения последовательность , …,, если она упорядочена по неубыванию или по невозрастанию; в противном случае удалить из последовательности те члены, порядковые номера которых кратны четырем, сохранив прежний порядок оставленных членов. Лабораторная работа №7. Двумерные массивы.
1. Дана действительная матрица размера . Найти среднее арифметическое наибольшего и наименьшего значения ее элементов.
2. Дана действительная матрица размера . Найти сумму наибольших значений элементов ее строк.
3. В данной действительной квадратной матрице порядка найти сумму элементов строки, в которой расположен элемент с наименьшим значением. Предполагается, что такой элемент единственный.
4. В данной действительной матрице размера поменять местами строку, содержащую элемент с наибольшим значением, со строкой, содержащей элемент с наименьшим значением. Предполагается, что эти элементы единственны.
5. В данной квадратной целочисленной матрице порядка 17 указать индексы всех элементов с наибольшим значением.
6. Дана целочисленная квадратная матрица порядка 8. Найти наименьшее из значений элементов столбца, который обладает наибольшей суммой модулей элементов. Если таких столбцов несколько, то взять первый из них.
7. Дана действительная квадратная матрица порядка 10. В строках с отрицательным элементом на главной диагонали найти сумму всех элементов.
8. Дана действительная квадратная матрица порядка . Рассмотрим те элементы, которые расположены в строках, начинающихся с отрицательного элемента. Найти суммы тех из них, которые расположены соответственно ниже, выше и на главной диагонали.
9. Даны натуральное число , действительная квадратная матрица порядка . Поострить последовательность из нулей и единиц, в которой тогда и только тогда, когда элементы -строки матрицы образуют возрастающую последовательность.
10. Дана целочисленная квадратная матрица порядка 15. Выяснить, имеются ли в матрице ненулевые элементы, и если имеются, то указать индексы всех ненулевых элементов.
11. Дана действительная квадратная матрица порядка 9. Вычислить сумму тех из ее элементов, расположенных на главной диагонали и выше нее, которые превосходят по величине все элементы, расположенные ниже главной диагонали. Если на главной диагонали и выше нее нет элементов с указанным свойством, то ответом должно служить сообщение об этом.
12. Дана действительная квадратная матрица порядка . Найти сумму элементов главной и побочной диагоналей.
13. Дана действительная квадратная матрица порядка . Найти наименьшее из значений элементов побочной диагонали и двух соседних с ней линий.
14. Дана действительная квадратная матрица порядка . Выяснить, верно ли, что наибольшее из значений элементов главной диагонали больше, чем наименьшее из значений элементов побочной диагонали.
15. Даны целые числа , целочисленная квадратная матрица порядка . Заменить нулями в матрице те элементы с четной суммой индексов, для которых имеются равные среди .
16. Дана целочисленная матрица размера . Найти матрицу, получающуюся из данной перестановкой столбцов – первого с последним, второго с предпоследним и т.д.
17. Дана целочисленная матрица размера . Найти матрицу, получающуюся из данной перестановкой строк – первой с последней, второй с предпоследней и т.д.
18. Дана действительная квадратная матрица порядка . Преобразовать матрицу по правилу: строку с номером сделать столбцом с номером , а столбец с номером сделать строкой с номером .
19. Даны две действительные квадратные матрицы порядка .Получить новую матрицу – умножением элементов каждой строки первой матрицы на наибольшее из значений элементов соответствующей строки второй матрицы.
20. В данной действительной квадратной матрице порядка найти наибольший по модулю элемент. Получить квадратную матрицу порядка путем выбрасывания из исходной матрицы какой-либо строки и столбца, на пересечении которых расположен элемент с найденным значением.
Лабораторная работа №8. Обработка последовательностей символов
Для всех упражнений данной лабораторной работы входной информацией является строка – последовательность английских слов, разделенных пробелами.
Дана строка символов, состоящая из строчных и прописных букв. Преобразовать строку, заменив все вхождения прописных букв на строчные. Дана строка, символов, содержащая буквы и пробелы. Преобразовать данную строку, заменив все внутренние группы пробелов одним пробелом. Дана строка символов, в которой есть хотя бы одна точка. Преобразовать строку символов, удалив из нее все символы «*», стоящие до первой точки, и заменить символы «-» на «+» после первой точки. Дана строка символов. В ней даны минимум два символа «кавычки». Вывести на экран набор символов, размещенных между данными кавычками. Дана строка символов, состоящая из букв и цифр. Вывести на экран число, состоящее из цифр данной строки. Дана строка символов, состоящая из букв и цифр. Подсчитать сумму всех цифр данной строки. Строка содержит одно слово максимальной длины и одно слово минимальной длины. Поменять их местами. Даны натуральное число n, символы , …, . Исключить из последовательности , …, . группы символов, расположенные между скобками ( ). Сами скобки тоже должны быть исключены. Предполагается, что внутри каждой пары скобок нет других скобок. Даны натуральное число n, символы , …, . Заменить в последовательности , …, каждую группу букв child группой букв children. Даны натуральное число n, символы , …, . Группы символов, разделенные пробелами (одним или несколькими) и не содержащие пробелов внутри себя, будем называть словами. Подсчитать количество слов в данной последовательности. Даны натуральное число n, символы , …, . Группы символов, разделенные пробелами (одним или несколькими) и не содержащие пробелов внутри себя, будем называть словами. Подсчитать количество английских букв а в последнем слове данной последовательности. Даны натуральное число n, символы , …, . Группы символов, разделенные пробелами (одним или несколькими) и не содержащие пробелов внутри себя, будем называть словами. Найти количество слов, начинающихся с буквы w. Даны натуральное число n, символы , …, . Группы символов, разделенные пробелами (одним или несколькими) и не содержащие пробелов внутри себя, будем называть словами. Найти количество слов, у которых первый и последний символы совпадают между собой. Даны натуральное число n, символы , …, . Группы символов, разделенные пробелами (одним или несколькими) и не содержащие пробелов внутри себя, будем называть словами. Найти какое-нибудь слово, начинающееся с английской буквы а. Даны натуральное число n, символы , …, . Группы символов, разделенные пробелами (одним или несколькими) и не содержащие пробелов внутри себя, будем называть словами. Преобразовать данную последовательность, заменяя всякое вхождение слова this на слово these. Даны символы , , …Известно, что символ отличен от пробела и что среди , , … имеется хотя бы один пробел. Рассматриваются , …, - символы, предшествующие первому пробелу (n заранее известно). Преобразовать последовательность , …, удалив из нее все символы, не являющиеся буквами. Даны символы , , …Известно, что символ отличен от пробела и что среди , , … имеется хотя бы один пробел. Рассматриваются , …, - символы, предшествующие первому пробелу (n заранее известно). Преобразовать последовательность , …, , заменив все малые буквы одноименными большими. Даны символы , , …Известно, что символ отличен от пробела и что среди , , … имеется хотя бы один пробел. Рассматриваются , …, - символы, предшествующие первому пробелу (n заранее известно). Преобразовать последовательность , …, , удалив все символы, не являющиеся буквами или цифрами, и заменив каждую большую букву одноименной малой. Даны символы , , …Известно, что символ отличен от пробела и что среди , , … имеется хотя бы один пробел. Рассматриваются , …, - символы, предшествующие первому пробелу (n заранее известно). Преобразовать последовательность , …, , удалив из каждой группы идущих подряд цифр, в которой более двух цифр и которой предшествует точка, все цифры, начиная с третьей (например, ab+0.1973-1.1 преобразуется в ab+0.19-1.1). Даны символы , , …Известно, что символ отличен от пробела и что среди , , … имеется хотя бы один пробел. Рассматриваются , …, – символы, предшествующие первому пробелу (n заранее известно). Преобразовать последовательность , …, , удалив из каждой группы цифр, которой не предшествует точка, все начальные нули (кроме последнего, если за ним идет точка). Лабораторная работа №9. Использование подпрограмм
1. Даны действительные числа , . Получить
,
где
.
2. Даны действительные числа , . Получить
,
где

Даны действительные числа , , . Получить .
Даны действительные числа , . Получить , , .
5. Даны действительные числа , . Получить
,
где
.
Даны действительные числа . Получить для значения , где .
Даны действительные числа , , . Получить , где .
Даны действительные числа , , , , …, , . Найти периметр десятиугольника, вершины которого соответственно координаты , , …, . Определить процедуру вычисления расстояния между двумя точками, заданными своими координатами. Дано натуральное число , действительные числа , , , , …, , . Найти площадь -угольника, вершины которого при некотором последовательном обходе имеют координаты , , …, . Определить процедуру вычисления площади треугольника по координатам его вершин. Дано четное число ; проверить для этого числа гипотезу Гольдбаха. Эта гипотеза (по сегодняшний день не опровергнута и полностью не доказана) заключается в том, что каждое четное , большее двух, представляется в виде суммы двух простых чисел. Определить процедуру, позволяющую распознавать простые числа. Дано натуральное число . Выяснить, имеются ли среди чисел , , …, близнецы, т.е. простые числа, разность между которыми равна двум. Определить процедуру, позволяющую распознавать простые числа. Дано натуральное число . Среди чисел 1, 2, …, найти все те, которые можно представить в виде суммы квадратов двух натуральных числе. Определить процедуру, позволяющую распознавать полные квадраты. Даны натуральные числа , ; найти . Используя программу, включающую рекурсивную процедуру вычисления , основанную на соотношении , где – остаток от деления на (см. лаб. раб. №3 задача 18). Чем эта программа хуже нерекурсивной программы вычисления ? Даны натуральные числа , , . Получить , где
.
Использовать программу, включающую рекурсивную процедуру вычисления .
Даны неотрицательные целые числа , ; вычислить , где
(это так называемая функция Аккермана).
Использовать программу, включающую рекурсивную процедуру.
Два натуральных числа называются «дружественными», если каждое из них равно сумме всех делителей другого, за исключением его самого (таковы, например, числа 220 и 284). Напечатать все пары «дружественных» чисел, не превосходящих заданного натурального числа. Даны координаты вершин двух треугольников. Определить, какой из них имеет большую площадь. Даны координаты вершин треугольника и координаты некоторой точки внутри него. Найти расстояние от данной точки до ближайшей стороны треугольника. При определении расстояний учесть, что площадь треугольника может вычисляться разными способами - через три его стороны или через основание и высоту. Три прямые на плоскости заданы уравнениями (). Если эти прямые попарно пересекаются и образуют треугольник, найти его площадь. Даны коэффициенты многочленов и 15-й степени и дано вещественное число . Вычислить величину

СОДЕРЖАНИЕ

Предисловие ___________________________________________________3
1. Общая схема решения задачи на персональном компьютере 6
2. Введение в язык Object Pascal. Общая структура программы. Идентификаторы, комментарии, пробелы. Раздел описаний и раздел операторов_____________________7
3. Арифметические типы данных. Числовые константы и переменные.
Оператор присваивания. Выражения__________________________________________8
4. Операторы ввода-вывода_________________________________________________11
5. Арифметические операции. Стандартные математические функции 13
6. Символьный тип данных_______________________ _____________ 17
7. Логический тип данных. Операции сравнения. Логические операции.
Битовые операции___________________________________________________18
8. Условный оператор. Блок. Оператор выбора 21
9. Операторы цикла_______________________ _23
10. Метки. Оператор GOTO. Процедура Halt 26
11. Интервальные типы данных. Оператор TYPE. Массивы____________27
12. Ошибки при выполнении программы. Опции компилятор __ 32
13. Процедуры и функции. Сфера действия описаний 34
14. Множества_________________________________ 38
15. Тип STRING________________________________________________40
17. Кое-что о вещественных вычислениях 51
18. Записи___________________________ 54
19. Тип "перечисление" _____________________________________57
21. Модули. Создание и использование модулей 60
22. Файлы_________________________________ 61
24. Указатели и динамическая память 68
25. Динамические структуры : списки, деревья 71
31. Некоторые вычислительные алгоритмы______________________80
32. Объекты__________________________ ____ 87


Не сдавайте скачаную работу преподавателю!
Данный конспект лекций Вы можете использовать для создания шпаргалок и подготовки к экзаменам.

Доработать Узнать цену работы по вашей теме
Поделись с друзьями, за репост + 100 мильонов к студенческой карме:

Пишем конспект самостоятельно:
! Как написать конспект Как правильно подойти к написанию чтобы быстро и информативно все зафиксировать.

Другие популярные конспекты:

Конспект Основные проблемы и этапы развития средневековой философии
Конспект Проблема познаваемости мира. Гносеологический оптимизм, скептицизм, агностицизм. Взаимосвязь субъекта и объекта познания
Конспект Понятие финансовой устойчивости организации
Конспект ПРОБЛЕМЫ КВАЛИФИКАЦИИ ПРЕСТУПЛЕНИЙ
Конспект Понятие мировоззрения, его уровни и структура. Исторические типы мировоззрения
Конспект Внутренняя политика первых Романовых.
Конспект Синтагматические, парадигматические и иерархические отношения в языке
Конспект Тема 1.2. Плоская система сходящихся сил. Определение равнодействующей геометрическим способом 13
Конспект Происхождение человека. Основные концепции антропосоциогенеза. Антропогенез и культурогенез.
Конспект Общая характеристика процессов сбора, передачи, обработки и накопления информации