- •1. Формулировка задачи
- •2. Представление данных и ограничения
- •3. Описание функций программы
- •3.1. Иерархическая схема
- •3.2. Прототипы функций
- •4. Алгоритм решения задачи
- •5. Тестовые наборы данных и реакции
- •6. Исходный текст программы
- •7. Описание тестирования программы
- •Анализ работы по решению задачи
7. Описание тестирования программы
Для тестирования и отладки программы был использован символический отладчик системы разработки Turbo C v. 2.0. Тест-реакции на числа и на управление повтором приведены в таблицах 5.1 и 5.2
Были использованы точки останова, указанные в таблице 7.1
7.1. Таблица точек останова
|
№ |
Файл |
Функция |
Оператор |
Просматриваемая переменная |
|
KТ1 |
main2.c |
Title |
printf() |
нет |
|
KТ2 |
myio2.c |
GetNum |
return n |
n |
|
KТ3 |
calc2.c |
Calc |
printf() |
k |
В результате работы были выявлены 2 синтаксические ошибки:
1. При компиляции программы произошел останов в файле calc2.c в функции main на строке:
calc ( ) ;
c диагностическим сообщением «Call to function ‘calc’ with no prototype in function main» (вызов функции ‘calc’ без прототипа в функции main). Причиной этого стало ошибочное написание названия собственной функции Calc. Для устранения ошибки необходимо исправить calc на Calc.
Было:
сalc ( ) ;
Стало:
Calc ( ) ;
2. При компиляции программы произошел останов в файле myio2.c в функции YesNo в строке:
char c
с диагностическим сообщением «Declaration syntax error in function YesNo» (синтаксическая ошибка в функции YesNo). Причиной этого стало отсутсвие ‘;’ после объявления переменной c. Для устранения этого необходимо поставить ‘;’ после c.
Было:
char c
Стало:
char c;
После устранения синтаксических ошибок и успешной сборки программы было начато устранение логических ошибок.
1. При тестовом наборе Begnum = -190, Maxnum = 5 ( тест № 1 из табл. 5.1. ) программа выводила на экран числа от 1 до 5 и их квадраты, запрос на повторный прогон программы и тут же сообщение о том, что работа закончена. Ошибка заключалась в том, что не было возможности управления для повторного прогона программы. Причиной данной ошибки являлось то, что буфер клавиатуры не был опорожнен перед тем, как из него читались данные, и поэтому переменная «с» содержала мусор. Для устранения ошибки был включен в код вызов функции опорожнения входного потока fflush ( stdin ).
Файл: myio2.c, функция YesNo.
Было:
printf ( “\n%s”, text );
c = getchar ( );
Стало:
printf ( “\n%s”, text );
fflush ( stdin );
c = getchar ( );
из тех же соображений был изменен код в функции GetNum.
Файл: myio2.с, функция GetNum.
Было:
printf ( “\n%s = “, query );
scanf ( “%d”, &n);
Стало:
printf ( “\n%s = “, query );
fflush ( stdin );
scanf ( “%d”, &n);
2. При тестовом наборе Begnum = -190, Maxnum = 5 ( тест № 1 из табл. 5.1 ) программа выводила на экран числа от 1 до 5 и их квадраты, что не являлось верным, т.к. программа не до конца использовала весь возможный диапазон. Причиной этому являлось неверное значение числовой константы, отвечающей за минимальное обрабатываемое число. Произведя анализ и оценку минимального вводимого числа, было внесено изменение в значение константы MINNUM ( табл. 2.1 ).
Файл: const.h
Было:
#define MINNUM 1 /* минимальное обрабатываемое число */
Стало:
#define MINNUM -181 /* минимальное обрабатываемое число */
3. При тестовом наборе Begnum = 200, Maxnum = 5 ( тест № 6из табл. 5.1 ) программа выводила на экран числа от 200 до 204 и квадраты – отрицательные числа, что не являлось верным, т.к. значение переменной выходило за представляемые границы типа int. Причиной этому являлось неверное значение числовой константы, отвечающей за максимальное обрабатываемое число. Произведя анализ и оценку максимального вводимого числа, было внесено изменение в значение константы MAXNUM ( табл. 2.1 ).
Файл: const.h
Было:
#define MAXNUM 2000 /* максимальное обрабатываемое число */
Стало:
#define MAXNUM 181 /* максимальное обрабатываемое число */
4. При тестовом наборе Begum = 10, Maxnum = 1 ( тест № 7, табл. 5.1. ) программа не выводила на экран таблицу результатов, что не являлось верным, т.к. программа должна выводить на экран хотя бы одну строку с результатами. Причиной этому являлось отсутствие числовой константы, отвечающей за минимальное количество строк, выводимых на экран, а также в функции GetPar при получении количества обрабатываемых чисел в переменную Maxnum функцией GetNum брался неверный параметр MINNUM. Произведя анализ и оценку минимального количества строк, выводимых на экран, была добавлена новая константа MINLINES ( табл. 2.1 ), а также в функции GetPar при получении количества обрабатываемых чисел в переменную Maxnum был исправлен список параметров функции GetNum.
Файл: const.h
Было:
#define MAXLINES 20 /* максимальное количество строк, выводимых на экран */
Стало:
#define MINLINES 1 /* минимальное количество строк, выводимых на экран */
#define MAXLINES 20 /* максимальное количество строк, выводимых на экран */
Файл: myio2.c, функция GetPar.
Было:
Maxnum = GetNum ( NUMBERS, MINNUM, MAXLINES );
Стало:
Maxnum = GetNum ( NUMBERS, MINLINES, MAXLINES );
5. При тестовом наборе Begnum = 10, Maxnum = 40 ( тест № 11 из табл. 5.1 ) строки с сообщениями умещались на экранеи при этом оставалось свободное место. Причиной этому являлось неверное значение числовой константы, ответственной за максимально количество строк, выводимых на экран. Произведя анализ и оценку максимального количества строк, выводимых на экран, было внесено изменение в значение константы MAXLINES ( табл. 2.1 ).
Файл: const.h
Было:
#define MAXLINES 20 /* максимальное количество строк, выводимых на экран */
Стало:
#define MAXLINES 23 /* максимальное количество строк, выводимых на экран */
6. При тестовом наборе Begnum = 181, Maxnum = 5 ( тест № 5 из табл. 5.1 ) программа выводила на экран число 181 и его верный квадрат, а также числа от 182 до 184 и их неверные квадраты – отрицательные числа. Причиной этого являлся тот факт, что не производилась проверка на совместность введенных данных, следствием чего являлся выход текущего числа за границы ОДЗ. Ошибка была устранена путем добавления в код функции GetPar проверки на совместность вводимых чисел и коррекции переменной Maxnum при необходимости. Проверка проводилась выражением:
Begnum + Maxnum > MAXNUM
Файл: myio2.c, функция GetPar.
Было:
Maxnum = GetNum ( NUMBERS, MINLINES, MAXLINES );
Стало:
Maxnum = GetNum ( NUMBERS, MINLINES, MAXLINES );
if( Begnum + Maxnum > MAXNUM )
Maxnum = MAXNUM – Begnum + 1;
7. При тестовом наборе Begnum + ‘a’, Maxnum = 5 ( тест № 12, табл. 5.1 ) программа каждый раз при повторной попытке выводила различные результаты, несоответствующие действительности, что неудачно, т.к. реакция программы на вводимую информацию должна быть однозначной. Причиной этого являлось содержание «мусора» в переменной n при вводе не численного значения. Для устранения этой ошибки требуется при вводе текста присваивать переменной n определенное значение ( значение середины диапозона от minnum до maxnum ).
Файл: myio2.c, функция GetNum.
Было:
scan( “%d”, &n );
if( n < minnum )
Стало:
scan( ( “%d”, &n ) != 1 );
n = ( minnum + maxnum ) / 2;
if( n < minnum )
8. Для того, чтобы сделать функции Title, GetNum и YesNo более универсальными и для уменьшения вероятности ошибок при дальнейшем использовании этих функций необходимо перенести все вспомогательные и управляющие символы вывода из текстов сообщений в формат printf(), в самих функции.
Файл: myio2.c, функция Title.
Было:
printf ( “%s”, SQUARES );
Стало:
printf ( “\n%s”, SQUARES );
Файл myio2.c, функция GetNum.
Было:
printf ( “%s”, text );
Стало:
printf ( “\n%s = ”, text );
Файл: myio2.c, функция YesNo.
Было:
printf ( “\n%s”, text );
Стало:
printf ( “\n%s[Y/N]? ”, text );
#else
Файл text2.c
Было:
char *SQUARES = "\n Integer squares output";
char *STARTNUM = "\n First value ";
char *NUMBERS = "\n Number of value ";
char *FINAL = "The work is finished!";
char *QUERY = "Repeat";
char *OUTMSG = "\nValue = %3d, its square = %5d";
#else
char *SQUARES = "\n Вывод квадратов целых чисел";
char *STARTNUM = "\n Начальное число";
char *NUMBERS = "\n Количество чисел";
char *FINAL = "Работа закончена!";
char *QUERY = "Повторить";
char *OUTMSG = "\nЧисло = %3d, его квадрат = %5d";
Стало:
char *SQUARES = "Integer squares output";
char *STARTNUM = "First value";
char *NUMBERS = "Number of value";
char *FINAL = "The work is finished!";
char *QUERY = "Repeat";
char *OUTMSG = "\nValue = %3d, its square = %5d";
#else
char *SQUARES = "Вывод квадратов целых чисел";
char *STARTNUM = "Начальное число";
char *NUMBERS = "Количество чисел";
char *FINAL = "Работа закончена!";
char *QUERY = "Повторить";
char *OUTMSG = "\nЧисло = %3d, его квадрат = %5d";
9. При отладке программы была замечена нерациональность вычислений в функции Calc, т.к. выражение (Begnum + i) вычисляется трижды. Для рационального вычисления и упрощения выражения необходимо ввести переменную, которой будет присваиваться значение выражения (Begnum + i).
Файл: calc2.c, функция Calc.
Было:
int i;
for ( i = 0; i < Maxnum; i++ )
printf ( OUTMSG, Begnum + i, (Begnum + i)*(Begnum - i) );
Стало:
int i, k;
for ( i = 0; i < Maxnum; i++ )
{
k = Begnum + i;
printf ( OUTMSG, k, k*k );
}
10. Несоответствие типов данных значения возвращаемого функцией getchar() и переменной, получающей это значение. Причиной являлось возврат функцией getchar значения типа int, в переменную, имеющую тип char. Для устранения проблемы требовалось сменить тип переменной на int.
Файл: myio2.c, функция YesNo.
Было:
int YesNo ( char *query )
{
char c;
Стало:
int YesNo ( char *query )
{
int c;
