Курсовой проект (2)
.pdfНИУ МЭИ
Кафедра Прикладной математики
Курсовой проект. «Вычисление значения выражения»
Студент: Деревянко А.В.
Группа: А-13-10
Преподаватель: Чибизова Н.В.
Москва 2011
Содержание
1.Постановка задачи.
2.Диаграммы классов.
3.Описание классов.
4.Реализация компонентных классов.
5.Реализация диалогов с пользователем.
6.Программная документация.
7.Список используемой литературы.
1. Постановка задачи
Вычислить значение выражения, содержащего арифметические операции и переменные и константы целого типа в восьмеричной системе счисления.
Выражение задаѐтся в виде строки. Оно может содержать знаки операций, скобки, имена переменных и константы соответствующего типа. В первую очередь необходимо произвести синтаксический анализ введѐнной строки. Если строка представляет собой правильное выражение, необходимо преобразовать выражение в постфиксную запись и вывести строку, представляющую собой полученную постфиксную запись. Затем вводятся значения переменных, вычисляется значение выражение и выводится полученный результат.
При разработке программы необходимо создать три класса (как минимум): для синтаксического анализатора, перевода в постфиксную запись и собственно вычисления результата.
2. Диаграмма классов
class Analiz { public:
char* text;
;
bool analiz(char *input);
class Postfix { public:
char *output;
char postfix(char *input); };
|
class Evaluation { |
|
public: |
|
int result; |
|
inline int eval(char postfix); |
Основная форма: |
}; |
Class Calc Analiz an;
Postfix bn;
Форма ввода переменных
Input
1.Основная форма получает входные данные (строка) и при нажатии кнопки «Анализ» передаѐт их в функцию analiz класса Analiz. Возможны 2 варианта развития событий:
a)Функция analiz возвращает 1, выводится сообщение о том, что выражение верно, выполнение программы продолжается (переход к пункту 2).
b)Функция analiz возвращает 0, выводится сообщение об ошибке и правильная часть введѐнного выражения (сообщение передаѐтся строкой text). В этом случае, происходит переход снова к пункту 1, программа так же ожидает новые входные данные и проверяет их.
2.Основная форма передаѐт выражение, полученное в результате работы функции analiz в функцию postfix. После выполнения функции, в главную форму передаѐтся строка в постфиксной записи.
3.Выполняется поcле нажатия кнопки «Вычислить». Из главной формы в функцию eval класса Evaluation пережаѐтся постфиксная запись выражения.
Если есть неизвестные переменные, функция eval запрашивает их ввод у пользователя через форму Input и производит контроль ввода (ввод должен
представлять собой отрицательное или положительное восьмеричное число). При вычислении результата производится проверка деления на 0 (т.к. ограничений на ввод нулевого значения переменной в форме Input быть не может). В случае возникновения попытки деления на 0 производится повторное выполнение пункта 3. Иначе, результат передаѐтся в главную форму и производится его вывод на экран.
3. Описание классов
Класс Analiz class Analiz { public:
char text[200]; //Строка – сообщение об ошибке и правильная часть выражения.
bool analiz(char *input); //функция-анализатор выражения. Ввод – исходное выражение
};
Класс Postfix |
|
class Postfix { |
|
public: |
|
char output[200]; |
//Выражение в постфиксной записи |
char postfix(char *input);//функция перевода в постфиксную запись. Ввод – выражение, |
|
}; |
// обработанное функцией analiz |
Класс Evaluation class Evaluation { public:
|
int oct_to_dec(int oct_num); //преобразование восьмеричной записи в десятичную |
|
int eval(char *postfix); //вычисление выражения. Принимаемые параметры – выражение в |
}; |
// постфиксной записи. |
4. |
Реализация компонентных функции |
|
|
Функция analiz
Проверяет выражение на типичные ошибки, при появлении которых прерывает выполнение проверки и выводит сообщение о том, что выражение неверно, ошибку и, в некоторых случаях, правильную часть выражения.
Каждый символ выражения проверяется на принадлежность к определѐнному типу функцией:
int strcheck(char c, char* strchecker) { //параметры: символ выражения; массив символов одного типа for (int i=0;strchecker[i];i++)
if (c==strchecker[i]) return 1;
return 0;
}
Ошибки выбираются оператором switch:
switch(stat){ |
|
case 1:texttemp = "Верно"; break; |
|
case 2:texttemp = "Пропущен операнд!"; break; |
|
case 3:texttemp = "Нехватает открывающейся скобки!"; break; |
|
case 4:texttemp = "Эти два оператора не могут следовать подряд!"; |
break; |
case 5:texttemp = "Пропущен оператор!"; break; |
|
case 6:texttemp = "Неверный символ!"; break; |
|
case 7:texttemp = "В восьмеричной системе нет 8 и 9!"; break; |
|
case 8:texttemp = "Выражение не может начинаться с этого оператора!"; break; case 9:texttemp = "Выражение не может заканчиваться оператором!";break;
case 10:texttemp = "Открывающаяся скобка ставится только после оператора!";break;
case 11:texttemp = "Этот оператор не может находиться после открывающейся скобки!";break; case 12:texttemp = "Оператор не может находиться перед закрывающейся скобкой!";break; case 13:texttemp = "После закрывающейся скобки может быть лишь оператор!";break;
case 14:texttemp = "Нехватает закрывающейся скобки!";break; case 15:texttemp = "Введите выражение!";break;
case 16:texttemp = "Пустые скобки запрещены!"; break;
case 17:texttemp = "Слишком много одинаковых операторов подряд!"; break; case 18:texttemp = "Деление на ноль!"; break;
}
Функция postfix
Производит перевод выражения в постфиксную запись.
Метод реализации:
1.Константы и переменные кладутся в формируемую запись в порядке их появления в исходном массиве.
2.При появлении операции в исходном массиве:
a.если в стеке нет операций или верхним элементом стека является открывающая скобка, операции кладѐтся в стек;
b.если новая операции имеет больший приоритет, чем верхняя операции в стеке, то новая операции кладѐтся в стек;
c.если новая операция имеет меньший или равный приоритет, чем верхняя операции в стеке, то операции, находящиеся в стеке, до ближайшей открывающей скобки или до операции с приоритетом меньшим, чем у новой операции, перекладываются в формируемую запись, а новая операции кладѐтся в стек.
3.Открывающая скобка кладѐтся в стек.
4.Закрывающая скобка выталкивает из стека в формируемую запись все операции до ближайшей открывающей скобки, открывающая скобка удаляется из стека.
5.После того, как мы добрались до конца исходного выражения, операции, оставшиеся в стеке, перекладываются в формируемое выражение.
Функция eval
Производит считывание постфиксной записи, константы кладутся в конец дека. В случае, если значение переменной неизвестно, оно запрашивается у пользователя формой ввода Input.
После нажатия кнопки ОК производится анализ ввода. Если ввод неверен, то выводится сообщение об ошибке и форма снова запрашивает ввод переменной, пока не будет введено положительное или отрицательное число (0 также возможен).
Проверка правильности ввода переменной производится функцией numarrcheck:
bool numarrcheck(char* c) { char* numarr = "01234567"; int z=0;
for(int i=0;numarr[i];i++) {
if (c[0]==numarr[i] || c[0]=='+' || c[0]=='-'){ z++; break;}
}
if(!z) return 0; for(int j=1;c[j];j++)
for (int i=0;numarr[i];i++){
if (c[j]==numarr[i]){ z++; break;}
}
if(z==strlen(c)) return 1; return 0;
}
Переменные и их значения записываются в словарь dict (Dictionary <String^,String^> dict). При появлении переменной в выражении, сначала проверяется еѐ принадлежность словарю, если переменная найдена, то в дек кладѐтся еѐ значение, взятое из словаря, иначе производится запрос ввода. Это предотвращает запрос одной переменной более одного раза (соответственно при вычислении выражения а а + а + ввод переменной а потребуется лишь один раз).
При вычислении выражения просматриваем постфиксную запись. Значения переменных и констант кладутся во временный стек. Когда встречается операция, из стека берутся два верхних значения, преобразуются в десятичную запись, вычисляется результат применения операции к этим значениям, и результат, преобразованный обратно в восьмеричную запись, помещается в стек.
При делении производится проверка деления на 0. В случае деления на 0, программа снова запрашивает ввод переменных и производит вычисление.
Если ошибок в процессе выполнения функции не происходит, выводится результат (верхнее значение во временном стеке).
5.Реализация диалогов с пользователем
Исходное состояние:
Кнопка «Вычислить», поля «Результат» и «Постфиксная запись» неактивны.
Введено верное выражение (a * (b + c) + d) / 2:
Выводится сообщение о том, что выражение верно, при нажатии кнопки ОК выводится постфиксная запись выражения, кнопка «Вычислить» становится активной.
При нажатии кнопки «Вычислить» производится запрос переменных:
После ввода переменных вычисляется результат (в восьмеричной системе), который выводится на экран, также в восьмеричной системе (на иллюстрации результат вычисления при a=2, b=6, c=10, d=7):
При нажатии кнопки «Выход» выполнение программы завершается.
Примеры обработки неверных выражений:
a) Введённое выражение: rows+329
b) Введённое выражение: rows32
c) Введённое выражение: rows+32)
d) Введённое выражение: rows+*32
e) Введённое выражение: rows$32
f) Введённое выражение: *rows
g) Введённое выражение: rows+
h) Введённое выражение: rows(32+1)
i) Введённое выражение: rows+(*32+1)
*Примечание: не имеет смысла далее описывать реализацию ошибок связанных со скобками, таких как: оператор установленный перед закрывающейся скобкой, отсутствие оператор после скобки. Их реализация аналогична
j) Введённое выражение: <пусто>
6. Программная документация
Файлы входящий в проект:
Calc.h
Analiz.cpp
Postfix.cpp
Evaluation.cpp
Курсовой проект.cpp
Input.h
Инструкция пользователю для работы с проектом:
1.Введите выражение в поле ввода.
В качестве констант допускается вводить положительные или отрицательные числа в
восьмеричной системе счисления.
Допускается ввод пробелов, но не допускается последовательности их >2 операторов. При этом выводится соответствующее сообщение об ошибке.
2.Нажмите кнопку «Анализ»
3.Если выражение верно, появится сообщение об этом и в поле «постфиксная запись» появится ваше выражение в постфиксной записи. Если вы получили сообщение об ошибке, снова выполните п. 1.
4.Если выражение содержит только константы, результат выполнения выражения можно увидеть в поле «Результат».
Если выражение содержит переменные, программа попросит вас их ввести. В этом случае руководствуйтесь правилами:
Нельзя вводить 0 в качестве переменной-делителя, при этом выводится соответствующее сообщение об ошибке, и снова запрашивается ввод переменной.
В качестве констант допускается вводить положительные или отрицательные числа в
восьмеричной системе счисления.
5.Результат выполнения выражения можно увидеть в поле «Результат»
7. Список используемои литературы
1.Б.Страуструп «Введение в язык C++».1995
2.Липпман «С++ для начинающих»
3.Шилдт Г. C++ Базовый курс
4.Библиотека http://msdn.microsoft.com/ru-ru/library.