Программирование (кодирование) или программная реализация алгоритмов
Словесную или графическую запись алгоритма обычно нельзя сразу ввести в ЭВМ, поэтому необходимо записать алгоритм на каком-либо языке программирования (ЯП). В результате получается программа на ЯП, которая вводится на ЭВМ и поступает на обработку в системную программу – транслятор (переводчик). Транслятор проверяет программу и выдаёт пользователю сообщение об ошибках. Если в программе ошибок нет, то транслятор переводит программу с ЯП на внутренний машинный язык ЭВМ. В результате получается машинная программа, которая управляет работой ЭВМ в процессе решения прикладной задачи. Переход от алгоритма к программе на ЯП называется кодированием алгоритма. Для каждого алгоритма можно построить несколько вариантов программы, поэтому при кодировании алгоритма нужно оптимизировать программу по лёгкости понимания, быстродействию и объёму памяти. Языки программирования можно разделить на 2 большие группы: алгоритмические и машинно-ориентированные.
Алгоритмический язык (АЯ) – это специальный искусственный язык, с помощью которого можно достаточно просто и удобно записать любой алгоритм. В настоящее время существуют сотни алгоритмических языков, например, наиболее известны следующие языки программирования: Фортран – язык для научно-технических расчётов; ПЛ/1, Кобол – языки для экономических расчётов; Бейсик – язык начального обучения; Паскаль – универсальный язык для обучения и программирования; Си – язык прикладного и системного программирования; Модула-2 и Ада – универсальные языки программирования; Лисп, Пролог – языки функционального и логического программирования; С++, Java, Object Pascal – языки объектно-ориентированного программирования. Часто вместо термина алгоритмический язык используется термин – язык программирования высокого уровня.
С технической точки зрения процесс кодирования алгоритма заключается в записи основных алгоритмических конструкций на языке программирования. Очень просто это можно представить в виде таблицы (табл.3), в которой сводятся основные алгоритмические конструкции и соответствующие им конструкции языка программирования.
Таблица 3.
Правила кодирования алгоритмов
№ | Язык Си | Язык Паскаль | ||
Блок начало | ||||
main() { | PROGRAM Name; BEGIN | |||
Блок конец | ||||
} | END. | |||
Операция присваивания: переменой x присвоить значение Z: x←Z | ||||
x = Z ; | x := Z; | |||
Разделение команд (операторов). Символ разделитель | ||||
; | ; | |||
Ввод данных | ||||
scanf ( &перем1, &перем2,…) [1]; | READ ( перем1, перем2,…); или READLN ( перем1, перем2,…); | |||
Вывод данных | ||||
printf ( перем1, перем2,…) 1; | WRITE ( перем1, перем2,…); или WRITELN ( перем1, перем2,…); | |||
Условие с двумя вариантами действий | ||||
if (Условие) { A;} else {B;} | IF (Условие) THEN BEGIN A; END ELSE BEGIN B; END; | |||
Условие с одним вариантом действий | ||||
if (Условие) { A;} | IF (Условие) THEN BEGIN A; END; | |||
Цикл с предусловием | ||||
while (Условие) { A; } | WHILE (Условие) DO BEGIN A; END | |||
Цикл с постусловием | ||||
do { A; } while (Условие) ; | REPEAT A; UNTIL (Условие ) ; | |||
Описание данных | ||||
main() { int i, j,…; // целые данные double x,y,z,…; // вещественные char c,p,…; // символьные char str[50]; // строковые … | PROGRAM FIRST; VAR i, j,… : INTEGER ; {целые данные} x,y,z,…: REAL ; {вещественные } c,p,… : CHAR; {символьные } str : STRING; {строковые} BEGIN … | |||
Подключение библиотек и модулей | ||||
//ОБЯЗАТЕЛЬНО! #include <stdio.h> #include <stdlib.h> #include <math.h> main() { … | {В случае необходимости} UNIT имямодуля-библиотеки; PROGRAM Name2; … | |||
Комментарий | ||||
// текст в одной строке или /* многострочный текст */ | { текст комментария в одну или несколько строк } или (* текст в одну или несколько строк *) или // текст в одной строке | |||
Машинно-ориентированный язык (МОЯ) – это язык машинных команд, записанных в символическом виде. Для обозначения таких языков применяются термины: язык ассемблера, автокод, мнемокод, язык символического кодирования и т.п. Программирование на машинно-ориентированном языке менее наглядно и более трудоёмко, чем программирование на АЯ. Однако в процессе работы с машинно-ориентированным языком можно учесть все особенности системы команд конкретной ЭВМ. Программа, составленная хорошим программистом на машинно-ориентированном языке, имеет лучшие характеристики по быстродействию и памяти, чем программа, полученная после трансляции с АЯ. Поэтому МОЯ применяются либо в системном, либо в высокоэффективном прикладном программировании.
Пример 5. Используя таблицу, закодируем на языках Си и Паскаль (рис.8) структурные алгоритмы решения задачи табулирования функции на основе цикла с постусловием (на языке Си) и цикла с предусловием (на языке Паскаль).
#include <stdio.h> #include <stdlib.h> #include <math.h> main() { double a,b,h,x,f ; scanf (&a, &b, &h); x = a; do { f = sin(x*x) - x; printf(x, f); x = x+h; } while ( x>b ); } | PROGRAM TABUL1; VAR a,b,h,x,f: REAL; BEGIN READLN (a, b, h); x := A; WHILE ( x<= B ) DO BEGIN f:=sin(x*x) - x; WRITELN(x, f); x:=x+h; END END. |
Рис.8. Реализация алгоритмов на языке Си и Паскаль
Примечание. На языке Си функции ввода-вывода scanf и printf имеют более сложный синтаксис, поэтому полученная в примере программа требует небольшой доработки. Программа на языке Паскаль получилась полностью работоспособной.
Тестирование и отладка
Тестирование – процесс поиска ошибок работы программы, посредством проверки правильности результатов ее функционирования на наборах данных, характерных для рабочего состояния программы. Как правило, при тестировании известны исходные данные и правильный результат, который должна выдавать программа. Такие данные часто называются тестовыми последовательностями или просто тестами. Цель тестирования – подготовить как можно больше тестовых последовательностей и проверить работоспособность программы на них.
Отладка – точное определение местоположения ошибок в программе, причин и условий их возникновения, с целью последующего их устранения.
Трассировка (раскрутка) алгоритма – это процесс пошагового выполнения алгоритма с записью в таблицу значений переменных, значений условий, номеров последующего шага (блока) для выполнения и комментариев по выполнению. Трассировка позволяет в ручном режиме, на бумаге проверить работу алгоритма и при необходимости найти ошибки. Фактически трассировка в таком виде заменяет стандартного исполнителя алгоритма – ЭВМ на исполнителя-человека. Важно, чтобы исполнитель действовал исключительно по инструкциям алгоритма, а не «фантазировал», что-то придумывал или изменял по ходу выполнения алгоритма.
Пример 6.Проведем трассировку структурного алгоритма на основе цикла с постусловием, приведенного в примере 4 (табл.4).
Таблица 4.
Трассировка(раскрутка) алгоритма
№ п/п | № шага | a | b | h | x | f | x>b | Примечание |
Начало | ||||||||
0,2 | Ввели в ячейки данные для a, b, h | |||||||
Записываем в ячейку x := a=1 | ||||||||
3, 3.1 | –0,159 | Начало цикла, вычисляем f:=sin 1 – 1 | ||||||
3.2 | На экран выводzтся ячейки x = 1 и f = –0,159 | |||||||
3.3 | 1,2 | x := x + h=1+0,2=1,2 | ||||||
3.4 | Нет | Проверка условия окончания цикла 1,2>2 | ||||||
3.1 | –0.209 | Вычисляем f:=sin (1,2) – 1,2= –0,209 | ||||||
3.2 | На экран выводится 1,2 и –0,209 | |||||||
3.3 | 1,4 | x := x + h=1,2+0,2=1,4 | ||||||
3.4 | Нет | Проверка условия окончания цикла 1,4>2 | ||||||
3.1 | –0.475 | Вычисляем f | ||||||
3.2 | На экран выводится 1,4 и –0,475 | |||||||
3.3 | 1,6 | x := x + h=1,4+0,2=1,6 | ||||||
3.4 | Нет | Проверка условия окончания цикла 1,6>2 | ||||||
3.1 | –1.051 | Вычисляем f | ||||||
3.2 | На экран выводится 1,6 и –1,051 | |||||||
3.3 | 1,8 | x := x + h=1,6+0,2=1,8 | ||||||
3.4 | Нет | Проверка условия окончания цикла 1,8>2 | ||||||
3.1 | –1.898 | Вычисляем f | ||||||
3.2 | На экран выводится 1,8 и –1,898 | |||||||
3.3 | 2,0 | x := x + h=1,8+0,2=2,0 | ||||||
3.4 | Нет | Проверка условия окончания цикла 2,0>2 | ||||||
3.1 | –2.757 | Вычисляем f | ||||||
3.2 | На экран выводится 2,0 и –2,757 | |||||||
3.3 | 2,2 | x := x + h=2,0+0,2=2,2 | ||||||
3.4 | Да | Проверка условия окончания цикла 2.2>2 | ||||||
Конец цикла, Конец работы алгоритма |
Верификация – доказательство правильности программы. Проблема верификации программ все еще является открытой, и в настоящее время существуют методы, позволяющие доказывать правильность лишь небольших и однотипных алгоритмов. Для сложных и больших алгоритмов методов верификации, к сожалению, пока не придумано. Более того, существует такая аксиома: любая сложная программа содержит хотя бы одну ошибку. Такое утверждение основывается на том факте, что в любой сложной программе с наличием циклов и ветвлений существует бесконечное (или очень большое) количество путей, и проверить работоспособность каждого пути, как правило, не представляется возможным, а значит вероятность того, что на одном из таких путей возникнет ошибка, достаточно велика. Фактически большинство методов верификации программ пытаются строго математически обойти все пути алгоритма и доказать, что ни на одном из них нет ошибок. При отладке программы, программист делает то же самое, – он пытается пройти все возможные пути и проверить на них работоспособность программы, но только не теоретическими методами, а практическим способом, выбирая различные тестовые последовательности, что бы охватить как можно большее количество путей в программе. Ошибки возникают именно на том пути, где программист не проверил работоспособность алгоритма.
Поэтому, для более тщательного тестирования и отладки программы, план проведения испытаний работы программы должен быть составлен заранее и тестовые данные должны подбираться для проверки функций программы, а не разработанных алгоритмов. Т.е. тестовые примеры создаются на этапе проектирования программной системы, а не на этапе кодирования.
Можно выделить следующие виды тестирования:
· автономное (тестирование модулей программистами);
· комплексное (тестирование общих функций системы программистами);
· системное (оценочное) – тестирование, как правило, с участием заказчика.