Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Курсовой проект (2)

.pdf
Скачиваний:
16
Добавлен:
28.06.2014
Размер:
1.07 Mб
Скачать

НИУ МЭИ

Кафедра Прикладной математики

Курсовой проект. «Вычисление значения выражения»

Студент: Деревянко А.В.

Группа: А-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.