- •ОСНОВЫ АЛГОРИТМИЗАЦИИ И ПРОГРАММИРОВАНИЯ
- •Требования к оформлению лабораторных работ
- •1. ОСНОВЫ АЛГОРИТМИЗАЦИИ И ПРОГРАММИРОВАНИЯ
- •13.1 План разработки алгоритмов и программ
- •Таблица 1.1 Результат ручной прокрутки после первого этапа
- •Таблица 1.2 Результат ручной прокрутки после первого этапа
- •Таблица 1.3 Итог выполнения ручной прокрутки
- •13.2 Перевод алгоритма в Паскаль-программу
- •13.3 Использование готовых алгоритмов при решении задач
- •Подсчет элементов, обладающих заданным свойством
- •Поиск максимального и минимального элементов
- •Поиск элементов, обладающих заданным свойством
- •Задача 1. Подсчет ненулевых элементов
- •Задача 2. Подсчет элементов, абсолютная величина которых больше 7
- •Задача 3. Поиск элемента равного 7
- •Задача 5. Найти количество элементов массива больших среднего арифметического этих элементов
- •Задача 6. Поиск максимального элемента и подсчет частоты его появления в массиве
- •Задача 7. Поиск нулевого элемента
- •Задача 8. Поиск отрицательного числа с конца массива
- •13.4 Стандартная обработка двумерных массивов
- •Двумерный массив и его части
- •Индексы элементов двумерного массива
- •Индексы строки и столбца двумерного массива
- •Индексы диагоналей двумерного массива
- •Перенос простейших алгоритмов на двумерные массивы
- •13.5 Отладка и тестирование программ
- •2. СОЗДАНИЕ КОНСОЛЬНЫХ ПРИЛОЖЕНИЙ СРЕДСТВАМИ DELPHI 7.0
- •13.1 Создание консольного приложения средствами Delphi
- •13.2 Структура программы в Delphi
- •Таблица 2.1
- •13.3 Введение в типы данных Delphi
- •13.4 Венгерская нотация
- •13.5 Отладка и тестирование программ средствами среды Delphi 7
- •3. ЛАБОРАТОРНАЯ РАБОТА №1 «ЛИНЕЙНЫЕ ПРОГРАММЫ»
- •13.1 Пояснения и примеры к лабораторной работе
- •13.2 Задания к лабораторной работе №1:
- •4. ЛАБОРАТОРНАЯ РАБОТА №2 «АЛГОРИТМЫ С ВЕТВЛЕНИЯМИ»
- •13.3 Пояснения и примеры к лабораторной работе
- •13.2 Реализация алгоритмов с ветвлениями средствами C#
- •13.3 Задания к лабораторной работе №2
- •5. ЛАБОРАТОРНАЯ РАБОТА №3 «ОПЕРАТОР ВЫБОРА»
- •13.1 Пояснения и примеры к лабораторной работе
- •13.2 Реализация оператора выбора в языке C#
- •13.3 Задания к лабораторной работе №3
- •6. ЛАБОРАТОРНАЯ РАБОТА №4 «ЦИКЛИЧЕСКИЕ АЛГОРИТМЫ»
- •13.1 Основные разновидности циклов
- •Цикл с постусловием
- •Цикл с предусловием
- •Цикл с параметром
- •Программное прерывание выполнения циклов
- •13.2 Примеры решения задач с использованием операторов цикла
- •Проверка корректности введенных данных
- •Решение задач с использованием диапазонов чисел
- •Решение задач полным перебором
- •Пояснения к задачам 18, 23, 24, 25:
- •13.3 Задания к лабораторной работе №4
- •7. ЛАБОРАТОРНАЯ РАБОТА №5 «РЯДЫ И ПОСЛЕДОВАТЕЛЬНОСТИ»
- •13.1 Примеры решения задач
- •Вычисление суммы n-первых членов ряда
- •Вычисление суммы n-первых членов последовательности, удовлетворяющих условию
- •Нахождение наименьшего номера члена последовательности, для которого выполняется некоторое условие
- •13.2 Задания к лабораторной работе №5
- •8. ЛАБОРАТОРНАЯ РАБОТА №6 «ТАБУЛИРОВАНИЕ ФУНКЦИЙ»
- •13.1 Пример решения задачи на табулирование функции
- •8.1.2 Организация перенаправления ввода-вывода средствами C#
- •13.2 Задания к лабораторной работе №6
- •9. ЛАБОРАТОРНАЯ РАБОТА №7 «ПОДПРОГРАММЫ»
- •13.1 Задания к лабораторной работе №7
- •13.2 Задания к лабораторной работе №8
- •13.1 Примеры и пояснения к лабораторной работе
- •13.2 Задания к лабораторной работе №9
- •Задания к лабораторной работе №10
- •13.1 Примеры работы со строками
- •Пример 13.2 Удалить из строки символ, указанный пользователем.
- •Пример 13.3 Удалить из строки лишних пробелов (пробелы в начале и в конце строки, между словами также должен быть один пробел).
- •Пример 13.4 Определить количество слов в заданном тексте.
- •13.2 Задания к лабораторной работе №11
- •13.1 Задания к лабораторной работе №12
- •13.1 Пояснения к работе
- •13.1 Задания к лабораторной работе №13
- •13.1 Пояснения к лабораторной работе №14
- •Формирование файла случайных чисел
- •Анализ файла случайных чисел
- •13.2 Задания к лабораторной работе №14
- •13.1 Примеры решения задач с использованием текстовых файлов
- •13.2 Задания к лабораторной работе №15
- •13.1 Задания к лабораторной работе №16
- •13.1 Задания к лабораторной работе №17
- •13.2 Задания к лабораторной работе №18
- •13.1 Задания к лабораторной работе №19
- •ПРИЛОЖЕНИЕ А
- •ПРИЛОЖЕНИЕ Б
- •СПИСОК РЕКОМЕНДУЕМОЙ ЛИТЕРАТУРЫ
- •ОГЛАВЛЕНИЕ
цедуры или функции, которых нет в модуле System. Посмотреть какие процедуры и функции входят в тот или иной модуль, а также как они реализованы можно следующим образом:
-Подключить необходимый модуль (дописать его в раздел uses), либо набрать имя процедуры или функции этого модуля;
-Удерживая клавишу CTRL, навести указатель на этот объект (при наведении идентификатор становится гиперссылкой) и кликнуть по ссылке, после чего откроется описание необходимого модуля.
Более подробную информацию по данным разделам можно получить из соответствующей литературы или конспекта лекций по информатике. Примеры применения отдельных разделов программы рассмотрены ниже в примерах решения задач, если в них возникает необходимость.
13.3 Введение в типы данных Delphi
Объем методического пособия не позволяет подробно рассмотреть типы данных и их применение для решения практических задач. Однако небольшое введение следует сделать.
Под типом данных понимается множество допустимых значений этих данных, а также совокупность операций над ними.
Таким образом, например тип Byte может принимать значения от 0 до 255, над переменными этого типа разрешены следующие математические операторы: +, *, -, div, mod, а также ряд функций.
Тип данных определяет, каким образом биты данных, представляющие конкретное значение, хранятся в памяти ПК. В каждом языке программирования имеется свой фиксированный набор базовых типов данных. Некоторые языки позволяют создание дополнительных (пользовательских) типов данных.
Типы данных 6ывают стандартные и пользовательские, кроме того, типы данных могут быть подразделены на простые и структурированные. К простым относятся целые типы, вещественные типы, логические типы, символьные, перечислимые, тип-диапазон, а к структурированным относятся такие типы, как массив, строки, записи и другие.
Общими тре6ованиями к использованию типов данных являются:
-минимизация о6ъема занимаемой памяти;
тип данных должен позволять разместить внутри себя все возможные
-значения, которые может принимать эта переменная.
Исходя из этого, например, для переменных, которые исполняют роль счетчиков, обычно используются в зависимости от максимального размера счетчика типы byte, word или longword.
Справку по типам данных Delphi смотри в приложении А.
25
13.4Венгерская нотация
Впрограмме типы данных назначаются переменным или константам, имена которых рекомендуется называть согласно венгерской нотации. Для каждого языка программирования существует свой набор сокращений и обозначений. Это делается для удобства чтения программ, однако перебарщивать с этим также не рекомендуется.
Следуя этой нотации, имя переменной состоит из четырех частей: признака, имени, префикса и суффикса. Обязательным является только признак.
Признак является сокращенным названием типа данных, например int. Далее идет имя переменной, которое характеризует ее, причем каждое слово в имени обычно пишется с большой буквы (слова разделены подчеркиванием Sum_Itog или не разделены никак SumItog). Таким образом, переменная, которая обозначает суммарный итог и тип этой переменной Integer, может иметь имя intSumItog. Для уточнения назначения переменной вводятся префиксы, например в имени переменной aintIndex префикс a обозначает массив (массив целочисленных индексов). В качестве суффиксов обычно используются max, min, first, last и т.д., которые вносят дополнительные уточнения в назначение переменных.
Итак, имя переменной полностью соответствующее венгерской нотации может выглядеть как: aintSumMax (максимальное значение целочисленного массива сумм).
Как уже говорилось выше, применение нотации необязательно, поэтому в примерах данного пособия наши переменные будут иметь только имя и признак, когда необходимо дополнительно пояснить их назначение.
13.5Отладка и тестирование программ средствами среды Delphi 7
Для запуска программы на исполнение необходимо нажать клавишу F9 или пункт меню Run -> Run. После чего компилятор проверяет наличие всех синтаксических и части смысловых ошибок, в случае их отсутствия программа начинает свою работу в консоли MS Windows, и вы сможете ввести тестовые данные либо посмотреть результат работы программы, в противном случае система выдает сообщение обо всех ошибках и помещает указатель за местом возникновения первой ошибки. В сообщении указывается тип ошибки и строка, в которой или перед которой произошла ошибка, при двойном клике на сообщении об ошибке указатель в окне редактора перейдет на нужную строку.
Тестирование программы производится с помощью отладчика (debugger), встроенного в Delphi. Встроенный отладчик позволяет выполнять все функции отладки описанные выше. Рассмотрим подробнее этап отладки программы в
26
среде программирования Delphi. Большинство средств отладки находится в меню Run. Клавиатурные комбинации некоторых из них приведены ниже:
-Пошаговое выполнение программы (трассировка) осуществляется при нажатии клавиши F7.
-Исполнение программы до курсора в редакторе F4.
-Продолжение исполнения программы без трассировки F9.
-Установка breakpoint производится установкой курсора на нужную строку и нажатием клавиши F5, либо кликом левой клавиши мыши по
полосе слева от текста.
Для установки условия для точки прерывания щелкните на красной точке breakpoint правой клавишей мыши и выберите в контекстном меню Breakpoint Properties и в пункте Condition введите условие, при котором вы хотели бы, чтобы программа приостановила свое выполнение, например sum>=100.
Для просмотра значений переменных, а также вычисления различных выражений в процессе отладки можно воспользоваться окном Watch. Его можно вызвать несколькими путями:
-Выбрав пункт меню View -> Debug Window -> Watches;
-Нажав комбинацию клавиш CTRL+ALT+W;
-Выбрав пункт меню Run -> Add Watch;
-Нажав комбинацию клавиш CTRL+F5;
Впоследних двух случаях вы сможете автоматически добавить в список переменных для просмотра нужную вам переменную или выражение.
Для добавления или редактирования списка просмотра вы также можете щелкнуть правой клавишей по окну Watch и в контекстном меню выбрать Add
Watch или Edit Watch.
27
3. ЛАБОРАТОРНАЯ РАБОТА №1 «ЛИНЕЙНЫЕ ПРОГРАММЫ»
Цель работы: Сформировать навыки по решению задач, используя линейные алгоритмы. Научиться использовать простые типы данных изучаемого языка программирования и математические возможности системы программирования.
13.1Пояснения и примеры к лабораторной работе
Вданной лабораторной работе вам предлагается решить три задачи, используя при этом средства линейных алгоритмов.
Линейным называется алгоритм, образованный последовательностью действий, следующих одно за другим.
Взадании 1.1 вам необходимо определить начальные значения, которые должен ввести пользователь, а также вывести на экран результирующее значение. Рассмотрим решение такой задачи на следующем примере:
Пример 3.1 В зависимости от переменных x, y, z найти значение выраже-
ния:
3 x5 +tg x (y) +e| x + y | log2 z
В данной задаче пользователь должен определить значения трех переменных x,y и z. После чего он должен увидеть результат вычислений на экране. Конечно, к значению переменной z следует предъявить некоторые ограничения, поэтому мы с вами обработаем возможное возникновение ошибки при помощи конструкции Try Except. Если вы обладаете необходимыми знаниями в программировании, то вы можете обработать ошибку другими способами, которые будут рассмотрены ниже.
Блок Try Except делится на две группы операторов, первая находится между оператором try и оператором except, а вторая между оператором except и оператором end. Конструкция работает следующим образом, если в ка- кой-то строке первой группы операторов произошла ошибка, то будет выполнен набор операторов второй группы, в противном случае вторая группа операторов будет пропущена.
Следует отметить, что при запуске в среде программирования блок try except игнорируется и ошибка исполнения прерывает работу программы. Данный блок работает при запуске исполнимого файла непосредственно в операционной системе.
28
Для составления системы тестов воспользуемся программой Mathcad или калькулятором, результаты заносим в таблицу 3.1.
Таблица 3.1 Система тестов
Номер |
|
Данные |
|
Результат |
||
теста |
x |
|
y |
|
z |
|
1 |
1 |
|
1 |
|
2 |
~11.9465 |
2 |
-1 |
|
-1 |
|
2 |
3.747 |
3 |
0 |
|
0 |
|
3 |
~1.6309 |
Далее приведены решение задачи в консольном приложении Delphi (листинг 3.1), в консольном приложении C# Visual Studio 2005 (листинг 3.2) и блоксхема к нему без учета блока обработки ошибок (Рис. 3.1).
Листинг 3.1
//Подключение модуля Math uses SysUtils, Math;
var x,y,z,f:double; begin
try
//Ввод переменных x, y, z write('x=');
readln(x);
write('y=');
readln(y);
write('z=');
readln(z);
f:= sin(y)/cos(y);
X, Y, Z
|
|
|
|
|
|
|
|
|
|
f= 3 x5 +tg x (y) |
+e |
| x + y | |
|
|
|
|
||||
|
|
|
|
log2 z |
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
f
Рис.3.1 Блок-схема для листинга 1
//Вычисление итогового значения выражения: f:=(3*x*x*x*x*x+Power(f,x))/(ln(z)/ln(2))+exp(abs(x+y)); writeln('result=',f:5:2); //Вывод на экран результата
except
writeln('Error'); // Вывод на экран сообщения об ошибке end;
end.
Для ввода переменных x, y, z в листинге 3.1 использована конструк-
ция:
write('x='); readln(x);,
которая позволяет пользователю видеть на экране сообщение типа х =, а затем в эту же строку ввести нужное значение указанной переменной.
Другой проблемой, с которой сталкивается программист в данном примере, является возведение числа в степень большую двух. В этом случае в зависимости от того, является показатель степени целым числом или нет, возможны различные пути решения. Если степень представляет собой целое число, то при его небольшом значении, можно реализовать ее как комбинацию
29
знаков умножит и/либо функции sqr.
Например, степень (х+y)5 может быть реализована как sqr(sqr(x+y))* (х+y) либо (х+y)* (х+y)* (х+y)* (х+y)* (х+y). Можно также реализовать степень, используя математическую формулу 3.1, в языке Pascal она будет вы-
глядеть как: exp(x*ln(a)).
a x =ex ln(a) |
(3.1) |
Однако данная формула воспринимает только положительные значения a, поэтому в листинге 3.1 использована функция power(a,x), входящая в модуль Math, который был предварительно подключен. Модуль Math содержит большое количество математических функций, которые вы можете использовать для решения задач. Список математических функций модуля System смотри в приложении Б.
Расчет логарифма по произвольному основанию выполнен в соответствии
с формулой 3.2, и имеет вид ln(z)/ln(2). |
|
||
log x a = |
ln(a) |
(3.2) |
|
ln(x) |
|||
|
|
Для вывода результата вычислений на экран применена процедура writeln('result=',f:5:2);. Отличие процедуры write от writeln состоит в том, что в первом случае указатель текучей позиции в консоли или в файле, куда производится запись, остается в той же строке, где он находился до этого, а в случае writeln вывод заканчивается добавлением признака конца строки (0D0Ah), что переводит курсор в следующую строку. Обе эти процедуры поддерживают форматный вывод. Форматный вывод позволяет определить, сколько позиций используется под переменную, при этом если переменная имеет длину меньшую чем указано, то недостающее количество позиций заполняется слева пробелами, а если количество символов в переменной больше чем указано в формате вывода, то переменная выводится целиком, и форматный вывод игнорируется. Например:
x:= 25;
write(x:4); //будет выведено ‘ 25’, где присутствуют два пробела слева x:= 65535;
write(x:4); // будет выведено ‘65535’.
Для вещественных чисел можно также указать количество символов после запятой, например writeln('result=',f:5:2); в результате переменная f будет выведена с двумя знаками после запятой. В этом же примере показано использование строковых констант для вывода.
Листинг 3.2 double x, y, z, f;
30
Console.Write("Введите переменную x: "); x = double.Parse(Console.ReadLine()); Console.Write("Введите переменную y: "); y = double.Parse(Console.ReadLine()); Console.Write("Введите переменную z: "); z = double.Parse(Console.ReadLine());
f =(3*Math.Pow(x,5) + Math.Pow(Math.Tan(y),x))/Math.Log(z,2)+ Math.Exp(Math.Abs(x+y));
Console.WriteLine("При x={0} y={1} z={2} f={3:F4}",x,y,z,f); Console.ReadLine();
Взадании 1.2 вам предлагается решить задачу, используя знания математики. Ее решение будет аналогично решению задания 1.1
Взадании 1.3 вам необходимо составить логическое выражение в соответствии с предложенным утверждением и вывести его в переменную логического типа.
Пример 3.2 Даны 3 утверждения. Определить их истинность: а) переменная х целое двузначное число;
b)переменная y является 6уквой латинского алфавита;
c)переменная z являете я полным квадратом.
Таблица 3.2 Система тестов
Номер |
Утверждение A |
|
Утверждение B |
Утверждение C |
|||||
теста |
x |
Результат |
|
y |
Результат |
z |
|
Результат |
|
1. |
25 |
|
True |
|
F |
True |
25 |
|
True |
2. |
25.3 |
|
False |
|
Я |
False |
45 |
|
False |
3. |
234 |
|
False |
|
5 |
False |
|
|
False |
Листинг 3.3 Решение задачи из примера 3.2 в Delphi 7 |
|
||||||||
var x, z:double; |
y:char; |
|
|
|
|
|
f1, f2, f3:Boolean; //Объявление логических переменных
begin
write('x='); readln(x); write('y='); readln(y); write('z='); readln(z);
//Вычисление и вывод результата для первого логического утверждения f1:= (x>9) and (x<100) and (trunc(x)=x);
writeln('result one:',f1);
//Вычисление и вывод результата для второго логического утверждения f2:=y in [‘A’..’Z’,’a’..’z’];
writeln('result two:',f2);
//Вычисление и вывод результата для третьего логического утверждения
F3:=sqrt(z)=trunc(sqrt(z)); writeln('result three:',f3);
end.
31
Первое логическое выражение проверяет условие 9<x<100 и целая часть от x равна самому x
Выражение y in [‘A’..’Z’,’a’..’z’] проверяет, входит ли переменная y во множество латинских букв
Третье логическое выражение проверяет, равен ли квадратный корень от z целой части этого корня. Полным квадратом, например, является число 25, т.к. квадратный корень из 25 равен 5, а 5 это целое число.
Листинг 3.4 Решение задачи из примера 3.2 в C# bool f1,f2,f3;
Console.Write("x=");
double h,x=double.Parse(Console.ReadLine()); Console.Write("y=");
char y=char.Parse(Console.ReadLine()); Console.Write("z=");
double z=double.Parse(Console.ReadLine()); f1=x>9 && x<100 && (int)x==x;
Console.WriteLine("Первое утверждение возвращает {0}",f1); f2=(y>='A' && y<='Z')||(y>='a' && y<='z'); Console.WriteLine("Второе утверждение возвращает {0}",f2); h=Math.Sqrt(z);
f3= h==(int)h;
Console.WriteLine("Третье утверждение возвращает {0}",f3); Console.ReadLine();
В задании 1.3 также встречаются задачи, где необходимо получить некоторую цифру, входящую в число, при этом пользоваться строковыми типами нельзя. Для нахождения цифр в числе можно использовать, например операторы div и mod в Pascal и операторы / и % в C#.
Пусть дано число x=123, тогда: Delphi, Pascal:
- первая цифра (1) может быть вычислена как x div 100;
- вторая цифра (2) может быть вычислена как x div 10 mod 10;
-третья цифра (3) может быть вычислена как x mod 10.
C#
-первая цифра (1) может быть вычислена как x / 100;
- |
вторая цифра (2) может быть вычислена как x /10 % 10; |
- |
третья цифра (3) может быть вычислена как x % 10. |
32