Рекомендации по кодированию программы
Из перечисленных в п.1.1.2 внешних спецификаций программного обеспечения Ваша курсовая работа должна включать
- текстовое описание решаемой задачи с указанием ограничений на исходные данные,
- дерево целей (результат декомпозиции решаемой задачи на более простые функции обработки, реализующие проверку ограничений);
- таблицы решений для каждой из выделенных функций (в соответствии с предыдущим пунктом),
- схему работы системы и схемы программ (для каждой выделенной функции) согласно ГОСТ 19.701-90,
- текст программы на каком-либо языке программирования (в качестве приложения).
При достаточно большой практике работы с общесистемным и прикладным программным обеспечением можно заметить, что одни программные продукты более ‘дружественны’ пользователю, другие - менее. Так, сообщения транслятора Турбо Паскаля об ошибке в программе, сформулированные на английском языке, очень часто приводят студентов в замешательство, особенно тех, кто изучал другой иностранный язык. Это пример того, как не нужно писать свои программы. Практический вывод, который студент может сделать и самостоятельно, таков:
- сообщения, формируемые программой, должны быть лаконичны, но содержать всю необходимую для принятия решения информацию (такие сообщения называют наиболее информативными).
Так, если при проверке файла F2 на корректность при неуникальных номерах или наименованиях предметов программист предусмотрит выдачу сообщения ‘в файле F2 обнаружена ошибка’, то при большом объеме информации в файле найти конкретную ошибку будет не так просто, поскольку из текста сообщения неясно, надо ли искать одинаковые номера или одинаковые наименования предметов или ошибку иного рода. Поэтому рекомендуем обратить внимание на приведенные в данном методическом пособии таблицы решений 2.4 - 2.6, в которых демонстрируются примеры подробных сообщений об обнаруженных ошибках.
Вторая рекомендация относится к проверке данных программой прежде, чем она начнет их обрабатывать. В противном случае программист не застрахован от ситуаций, аналогичных вычислению площади по трем сторонам, одна из которых больше суммы двух других сторон, или, например, от получения отрицательных значений времени. Поэтому, создавая свои программы, возьмите за правило:
- программа должна принимать от пользователя любые данные, однако, если введенная информация не является допустимой, программа должна информировать об этом пользователя.
Кодирование программы обработки, соответствующей заданию на курсовую работу, может быть выполнено на языках программирования Турбо Паскале или Си. Ниже приводятся необходимые сведения для обработки данных из текстовых файлов в программах на каждом из перечисленных языков программирования.
В Турбо Паскале различают текстовые файлы, типированные файлы и нетипированные файлы /3/.
При работе с файлами ключевым понятием является понятие переменной файлового типа или файловой переменной (ФП). В зависимости от класса файла ФП описывается одним из следующих способов:
- VAR<имя ФП>:Text - для текстового файла;
- VAR<имя ФП>:File of<Тип компонентов> - для типированного файла;
- VAR<имя ФП>:File - для нетипированного файла.
ФП связывается с именем файла оператором
ASSIGN(<ФП>’<путь к файлу>\<имя конкретного файла>’).
Этот оператор должен быть первым среди операторов, работающих с файлом. В кавычках указывается внешнее имя файла. Если во внешнем имени отсутствует указание пути, файл ищется в текущей директории.
Прежде чем станут доступны для чтения компоненты файла, его необходимо открыть оператором RESET(<ФП>), после чего автоматически текущим становится компонент с номером 0. Для чтения компонентов файла используются процедуры Readln и Read.
Текстовый файл не является однородной последовательностью символов, его компонентами являются строки, заканчивающиеся маркерами конца строки Eoln (занимает 2 байта и содержит коды: #13).
При работе с текстовым файлом список ввода (вывода) может содержать переменные символьного, строкового и любого числового типа. Запрещены в списке ввода (вывода) переменные-структуры (запись, массив, множество), но можно вводить из текстового файла простые значения полей записей или элементов массива.
Компоненты файла F1 могут иметь в программе следующее описание:
Var
FIO: String[20];
NGR: String[9];
X: String[1];
NPR, REZ: Word;
в описании фиксируется, “ФИО студента” занимает 20 позиций в записи компоненты текстового файла, следующий за этим полем пробел и номер группы (NGR) занимают 9 позиций, затем следует один пробел (Х) и целочисленные поля номер предмета (NPR) и оценка (REZ).
Положим, что файл F1 имеет внешнее имя “Rezses.dat” и помещен в ту же директорию, что и файл программы, и приведём операторы доступа в программе к компонентам файла F1:
Var
f: text;
Begin
Assign(f, ‘Rezses.dat’);
Reset(f);
While not EOF(f) do
Begin
readln(f, FIO, NGR, X, NPR, REZ);
{операторы обработки данных из записи}
End;
Close (f)
End.
Отметим, что процедура Readln считывает строку от начала всякий раз, как только все перечисленные в списке ввода переменные получат значения, остаток строки (если он есть) вместе с маркером конца строки пропускается и программа готова читать следующую строку из файла для чтения. При вводе значения символьной переменной оператор Read считывает в неё очередной символ строки, в том числе и символы маркера конца строки или конца файла. При вводе значений числовой переменной символы считываются вплоть до пробела, символа табуляции, маркера конца строки или конца файла и интерпретируются, как одно значение.
Доступ к полям записи файла F1 можно было получить в программе и другим способом, описав запись F1, как строку символов (длина строки=20+1+8+1+1+1+1+2=35, где последним слагаемым являются 2 символа Eoln-маркера конца строки).
Type
Stro=String[35];
Var
fp: File of Stro;
NGR:String[8];
m, NPR, REZ:Word;
S:Stro;
Begin
Assign (fp, ‘Rezses.dat’);
Reset(fp);
Repeat
Read(fp, s);
NGR:=Copy (S,22,8);
Val (Copy (S, 31, 1), NPR, m);
if m<>0 then Writeln (‘нечисловой номер предмета’);
Val (Copy (S, 33, 1), REZ, m);
if m<>0 then Writeln(‘нечисловая оценка’);
{другие операторы обработки}
Until EOF (fp);
Close (fp)
End.
В языке СИ файлы рассматриваются как неструктурированные последовательности байтов, ввод-вывод которых осуществляется библиотечными функциями /9/. Библиотека языка СИ поддерживает несколько уровней ввода-вывода, из них для выполнения стандартных операций применяют ввод-вывод, ориентированный на поток. Функции библиотеки, поддерживающие такой обмен данными с файлами на уровне потока, позволяют обрабатывать данные разных размеров и форматов, обеспечивая при этом буферизированный ввод-вывод. Таким образом, согласно концепции языка СИ, поток - это файл вместе с предоставляемыми средствами буферизации.
Для того, чтобы можно было использовать функции библиотеки ввода-вывода, в программу необходимо включить заголовочный файл stdio.h,который содержит прототипы функций ввода-вывода, а также определения констант, типов и структур, требуемых для работы функций обмена с потоком.
Данные в файле становятся доступными после его открытия. При этом в исполняемой программе поток связывается со структурой предопределеннного типа FILE. Определение структурного типа FILE включено в заголовочный файл stdio.hи включает: указатель на буфер, указатель (индикатор) текущей позиции в потоке и другие аналогичные компоненты, поддерживающие обмен с потоком. При открытии потока в программу возвращается указатель на поток, который является адресом объекта структурированного типа FILE( иначе говоря, совокупности всех тех компонент, о которых упоминалось выше). Этот указатель и будет определять поток во всех последующих операциях и должен быть объявлен в программе, например, следующим образом:
# include < stdio.h >
FILE *fp.
Объявленный указатель fp приобретет конкретное значение в результате выполнения функции открытия потока:
fp = fopen (имя_файла, режим_открытия).
Параметры имя_файла и режим_открытия являются строковыми данными, содержащими соответственно внешнее имя файла, связанного с потоком, и символьное обозначение режима открытия, например:
fp = fopen (²t.txt², ²r²),
гдеt.txt - внешнее имя файла данных в текущем каталоге; rобозначает режим работы с файлом (тип доступа к потоку).
Стандартно файл, связанный с потоком, можно открыть в одном из следующих режимов:
- ²r² означает открытие для чтения существующего текстового файла;
- ²w² открывает для записи новый текстовый файл, причем если файл с таким внешним именем уже существует на носителе, то его содержание будет потеряно;
-²a² открывает существующий текстовый файл для дозаписи (добавления новой порции) информации;
-²r+² означает открытие существующего текстового файла как для чтения, так и для изменения содержимого файла;
- ²w+² открывает новый текстовый файл для чтения-записи и последующих многократных изменений содержимого файла, причем если файл уже существует, то предыдущее содержимое стирается;
-²a+² открывает существующий текстовый файл для добавления или создает новый текстовый файл (если на носителе такого файла нет).
Обратите внимание, что во всех вышеперечисленных случаях поток открывается в текстовом режиме, для которого характерно, что прочитанная из потока комбинация символов CR (значение 13 - управляющий код ‘возврат каретки’) и LF (значение 10 - управляющий код ‘перевод строки’) преобразуется в один символ ‘\n’, имеющий значение, совпадающее с LF. При записи в поток в текстовом режиме осуществляется обратное преобразование ( т.е. символ ‘\n’ заменяется последовательностью CR LF). Если поток открыт для изменений, т.е. в параметре режима присутствует символ ‘+’, то разрешен как вывод в поток, так и чтение из него.
При открытии потока могут возникать такие характерные ошибки, когда на диске не найден файл, связанный с потоком, диск заполнен или защищен от записи. В таких случаях указатель на поток приобретает значение NULL, которое определено в файле stdio.h. Заметим, что значение указателя на поток в любом режиме, отличном от вышеуказанных ошибочных ситуаций, не бывает равным NULL. Поэтому типичная последовательность операторов при открытии текстового файла, связанного с потоком, и с проверкой ошибочных ситуаций может быть следующей:
if ((fp=fopen(²t.txt², ²w²))= = NULL)
{
perror (²ошибка при открытии файла t.txt \n²);
exit (0);
}
Для вывода на экран дисплея сообщения об ошибке при открытии потока используется стандартная библиотечная функция perror (), прототип которой находится в stdio.h.
После того, как файл открыт, конкретные значения полей записей файла можно либо считывать из него, либо записывать в файл (в зависимости от режима). Когда все операции с данными файла закончены, файл рекомендуется закрывать явно, для чего используется библиотечная функция fclose (указатель_на_поток). После закрытия файл может быть открыт повторно в другом режиме (этот прием часто используется, когда в одной программе создается новый файл, а затем информация из него обрабатывается согласно некоторому алгоритму).
Следует обратить внимание, что понятие текстового файла в языках программирования Паскаль и СИ не эквивалентны, единственным общим свойством является то, что в обоих языках в текстовых файлах записи отделяются друг от друга комбинацией кодов ‘возврат каретки’ и ‘перевод строки’. Понятию текстового файла Паскаля как совокупности записей из полей данных символьного типа в языке СИ соответствует текстовый файл форматного ввода-вывода, который создается стандартным текстовым редактором EDIT MS DOS или блокнотом Notepag. Достоинством файлов такого типа является то, что конкретные значения полей записей из них могут непосредственно отображаться на экран дисплея без преобразования вьюером VIEW. Логичнее было бы во всех языках программирования и системах программирования такие файлы называть символьными, что могло бы исключить разночтение.
В языке программирования СИ ввод-вывод таких файлов выполняется функциями fscanf () и fprintf(), которые имеют следующие прототипы:
int fscanf (указатель_на_поток, форматная_строка, список_адресов_переменных);
int fprintf (указатель_на_поток, форматная_строка, список_адресов_переменных).
Эти функции очень схожи с функциями scanf () и printf() для форматного обмена с клавиатурой и дисплеем, отличие лишь в том, что в случае обмена, ориентированного на поток, в качестве первого параметра функций требуется задавать указатель на поток, с которым производится обмен.
Для полноты изложения приведем фрагмент программы на языке СИ, включающий операторы чтения результатов сессии из вышеприведенного файла Rezses.dat:
# include < stdio.h >
void main()
{
char fio[21], ngr[9];
int npr,rez;
FILE *f;
if ((f=fopen(²Rezses.dat², ²r²))= = NULL)
{
perror (²ошибка при открытии файла Rezses.dat \n²);
exit (0);
}
while ( fscanf(f, ²%s%s%d%d², fio, ngr, &npr,&rez)!=EOF);
{ операторы обработки данных из записи}
fclose(f);
}
Тестирование программы
Согласно изложенной в 2.2.3 методики тестирования спецификаций необходимо разработать как минимум один тест на каждый столбец таблиц решений 2.4- 2.6, т.е. всего 17 тестов. Полное тестирование приводить в данной методической разработке вряд ли имеет смысл из-за его громоздкости, поэтому ограничимся двумя тестами, на которых продемонстрируем примеры изложения в отчете целей и результатов тестирования.
2.8.1.Тестирование функции “проверка на корректность F2”.
Цель теста: проверить функционирование программы при неуникальных номерах предметов.
Содержание теста: файл F2 включает записи, приведенные в таблице 2.7.
Таблица 2.7
Содержание файла F2
Номер предмета | Наименование предмета |
Математика | |
Физика | |
Химия | |
Иностранный язык | |
Алгоритмические языки |
Ожидаемый результат: сообщение ‘2-м предметам физика, химия присвоен один номер 2’.
Фактический результат: совпадает с ожидаемым.
Результат тестирования: неуспешный.
2.8.2. Тестирование функции “формирование строк выходной таблицы”.Цель теста: проверить функционирование программы при несовпадении номеров предметов в файлах F1 и F2.
Этот тест должен обеспечить в файле F1 такой номер предмета, который отсутствует в справочной файле F2. Программа должна выдать предупреждающее сообщение о несовпадении и продолжить работу. Содержание соответствующего теста отражено в таблицах 2.8, 2.9.
Таблица 2.8
Содержание файла F2.
Номер предмета | Наименование предмета |
Математика | |
Физика | |
Химия | |
Иностранный язык | |
Алгоритмические языки |
Таблица 2.9
Содержание файла F1.
ФИО студента | Номер группы | Номер предмета | Оценка |
Иванов И.И. | Т28-Т210 | ||
Сидоров С.А. | Т28-Т210 | ||
Смирнов А.А. | Т28-Т210 | ||
Петрова М.С. | Т28-Т210 | ||
Иванов И.И. | Т28-Т210 | ||
Петров П.В. | Т28-Т210 | ||
Иванов И.И. | Т28-Т210 |
Ожидаемый результат представляет собой выходной документ на экране дисплея, содержание которого приведено между горизонтальными линиями ниже.
___________________________________________________________
Номер группы | Наименование предмета | Оценка | Количество оценок в группе |
Т28-Т210 | Математика | ||
Физика | |||
Алгоритмические языки | |||
Т28-Т211 | Математика |
Не найдено наименование, соответствующее номеру предмета 6
Фактический результат: совпадает с ожидаемым.
Результат тестирования: неуспешный.
Оформление и содержание курсовой работы
Курсовая работа “специфицирование и тестирование программы” должна включать:
§ титульный лист (пример оформления показан в приложении А);
§ содержание работы (пример оформления приводится в приложении Б);
§ краткие теоретические сведения об этапах жизненного цикла программного продукта и месте и значении в нем этапов анализа, специфицирования и тестирования программ;
§ задание на курсовую работу (в приложении В приведен вариант типового задания);
§ описание ограничений, накладываемых на входные данные (см. п.2.3);
§ структуру целей разрабатываемой программы (см. рисунок 2.1);
§ таблицы решений для функций программы (см. таблицы 2.4- 2.6);
§ схему работы системы (см. рис 2.2);
§ схемы программ для всех выделенных в пункте ефункций;
§ содержание тестов и результаты тестирования функций программы (см. п. 2.8);
§ текст программы (на машинном носителе);
§ заключение в виде вывода о том, отвечает ли разработанная программа своим внешним спецификациям.
Список литературы
1. Липаев В.В., Филинов Е.Н. Мобильность программ и данных в открытых информационных системах. - М.: Научная книга, 1997. - 368 с.
2. Липаев В.В. Тестирование программ. -М.: Радио и связь, 1986.- 296 с.
3. Культин Н.Б. С/С+ + в задачах и примерах. – СПб.: БХВ-Петербург, 2004. – 288 с.
4. Калянов Г.Н. CASE структурный системный анализ (автоматизация и применение). - М.: ЛОРИ, 1996. - 242 с.
5. Майерс Г. Искусство тестирования программ. - М: Финансы и статистика, 1982.- 176 с.
6. Технологии разработки программного обеспечения. Учебное пособие. 2-е изд. / С.А. Орлов. – СПб.: Питер. 2003. – 480 с.
7. Фаронов В.В. Турбо Паскаль 7.0. Практика программирования: Учеб. пособие.- 7-е изд., перераб. – М.: Нолидж, 2003. – 432 с.
8. Иванова Г.С. Технология программирования: Учебник для вузов.- 2-е изд., стереотип. – М.: МГТУ им, Баумана, 2003. – 320 с.
9. Подбельский В.В. СИ + +: Учеб. пособие. –5-е изд. М.: Финансы и статистика, 2001.- 560 с.
10. Выполнение схем алгоритмов, программ, данных и систем: Методическме указания к курсовому и дипломному проектированию / Уфимск. Гос. Авиац. техн. ун-т; Сост.: Р.Г. Валеева, Г.Р. Валеева. – Уфа, 2003. – 23 с.
11. Керниган Б., Ритчи Д. Язык программирования С. – СПб.: Невский диалект , 2000 – 417 с.
ПРИЛОЖЕНИЕ А
Титульный лист курсовой работы
——————————————————————————————————
Министерство образования и науки Российской Федерации
УФИМСКИЙ ГОСУДАРСТВЕННЫЙ АВИАЦИОННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ
Кафедра технической кибернетики