Коды классов, функций и обработчиков событий


Сохраните модуль под именем LR_5, а проект – под именем PR_LR_5.

Достаточно полное представление об интерфейсе можно получить из рис.5.1, рис.5.2 и заголовочного файла LR_5.h (см. ниже). Отметим лишь, что для компонентов Label1,..,8 и Edit1,..,8 установлен шрифт Font = жирный, размер 10, а сконструированное меню представлено на рис.5.2.

Все функции – для работы со стеком и записями арифметических выражений, а также данные для функций поместим в класс Stack, содержание которого представлено на рис.5.3.

Для размещения класса в проекте использован модуль, не связанный с формой. Чтобы создать такой модуль, нужно выполнить команду Файл/Новый/Другое… и открывшемся окне Новые элементы на странице Новый щелкнуть на пиктограмме Модуль. Модулю дано имя f_5. В заголовочном файле этого модуля f_5.hнаходятся объявления структурных типов для стеков и класса, а в файле реализации модуля f_5.cpp – реализация класса (определения функций-элементов класса).


Рис.5.1 – форма по окончании проектирования

Рис.5.2 - видна структура меню Рис.5.3 - структурные типы и классы

Заголовочный файл LR_5.h модуля LR_5

//---------------------------------------------------------------------------

 

#ifndef LR_5H

#define LR_5H

//---------------------------------------------------------------------------

#include <Classes.hpp>

#include <Controls.hpp>

#include <StdCtrls.hpp>

#include <Forms.hpp>

#include <Menus.hpp>

#include <ActnList.hpp>

#include <ImgList.hpp>

#include <ComCtrls.hpp>

#include <ToolWin.hpp>

//---------------------------------------------------------------------------

class TForm1 : public TForm

{

__published: // IDE-managed Components

TLabel *Label1;

TLabel *Label2;

TEdit *Edit1;

TEdit *Edit2;

TLabel *Label3;

TEdit *Edit3;

TLabel *Label4;

TEdit *Edit4;

TLabel *Label5;

TEdit *Edit5;

TLabel *Label6;

TEdit *Edit6;

TLabel *Label7;

TEdit *Edit7;

TLabel *Label8;

TEdit *Edit8;

TActionList *ActionList1;

TImageList *ImageList1;

TAction *ANew;

TAction *AMod;

TAction *ARun;

TAction *AExit;

TMainMenu *MainMenu1;

TMenuItem *N1;

TMenuItem *N2;

TMenuItem *N3;

TMenuItem *N4;

TMenuItem *N5;

TMenuItem *N6;

TToolBar *ToolBar1;

TToolButton *ToolButton1;

TToolButton *ToolButton2;

TToolButton *ToolButton3;

TToolButton *ToolButton4;

void __fastcall FormCreate(TObject *Sender);

void __fastcall N2Click(TObject *Sender);

void __fastcall N3Click(TObject *Sender);

void __fastcall N4Click(TObject *Sender);

void __fastcall N6Click(TObject *Sender);

private: // User declarations

public: // User declarations

__fastcall TForm1(TComponent* Owner);

};

//---------------------------------------------------------------------------

extern PACKAGE TForm1 *Form1;

//---------------------------------------------------------------------------

#endif

 

Заголовочный файл f_5.hмодуля f_5

//---------------------------------------------------------------------------

 

#ifndef f_5H

#define f_5H

//---------------------------------------------------------------------------

//структура для элемента стека операций

struct Node_op

{

char c;

Node_op* p;

};

//---------------------------------------------------------------------------

//структура для элемента стека чисел

struct Node_num

{

float c;

Node_num* p;

};

//---------------------------------------------------------------------------

//перечисление для контроля ошибок при вводе

typedef enum {all_true=1, bad_operands, few_brackets, much_brackets,

few_operands, few_operators}errors;

//---------------------------------------------------------------------------

class Stack

{

public:

char* s; //исходная строка

char* sv; //вспомогательная строка

Node_op* t1; //указатель на вершину стека операций

Node_num* t2; //указатель на вершину стека чисел

void Stack_init(); //задание параметров объекта класса

void check(); //проверка корректности введенного выражения

void revers_before(); //реверсирование входной строки

void revers_after(); //реверсирование постфиксной записи

void bspaces(); //расстановка пробелов в строке

void postfix(); //преобразование в постфиксную запись

float calc(); //вычисление выражения в постфиксной записи

void out_err_code(); //вывод сообщения

errors err_code; //код ошибки

~Stack(); //деструктор класса

private:

int prioritet_stack();//определение приоритета оператора на вершине //стека

bool operand_true(char c); //проверка корректности операнда

void first1(char c); //создание стека операций

void push1(char c); //добавление в стек операций

char pop1(); //выталкивание из стека операций

void first2(float c); //создание стека чисел

void push2(float c); //добавление в стек чисел

float pop2(); //выталкивание из стека чисел

};

#endif

 

Файл реализации f_5.cppмодуля f_5

//---------------------------------------------------------------------------

 

#pragma hdrstop

 

#include "f_5.h"

#include "string.h"

#include "stdlib.h"

//---------------------------------------------------------------------------

 

#pragma package(smart_init)

void Stack::Stack_init()

{

t1=0;

t2=0;

s=new char[100];

sv=new char[100];

err_code=all_true;

}

//-------------------------------------------------------------------------

Stack::~Stack()

{

delete[] s;

delete[] sv;

}

//---------------------------------------------------------------------------

void Stack::first1(char c)

{

Node_op* pv=new Node_op;

pv->c=c;

pv->p=0;

t1=pv;

}

//---------------------------------------------------------------------------

void Stack::push1(char c)

{

Node_op* pv=new Node_op;

pv->c=c;

pv->p=t1;

t1=pv;

}

//--------------------------------------------------------------------------

char Stack::pop1()

{

char z=t1->c;

Node_op* pv=t1;

t1=t1->p;

delete pv;

return z;

}

//--------------------------------------------------------------------------

void Stack::first2(float c)

{

Node_num* pv=new Node_num;

pv->c=c;

pv->p=0;

t2=pv;

}

//---------------------------------------------------------------------------

void Stack::push2(float c)

{

Node_num* pv=new Node_num;

pv->c=c;

pv->p=t2;

t2=pv;

}

//--------------------------------------------------------------------------

float Stack::pop2()

{

float z=t2->c;

Node_num* pv=t2;

t2=t2->p;

delete pv;

return z;

}

//--------------------------------------------------------------------------

bool Stack:: operand_true(char c)

{

if(c>='0'&&c<='9'||c>='A'&&c<='Z'||

c>='a'&&c<='z'||c=='.') return true;

else return false;

}

//---------------------------------------------------------------------------

int Stack::prioritet_stack()

{

if(t1->c=='(')return 3;

if(t1->c=='+'||t1->c=='-')return 1;

return 2;

}

//---------------------------------------------------------------------------

void Stack::check()

{

int sk=0;

int rang=0;

int l=strlen(s);

int i=0;

if(s[0]==')')

{err_code=much_brackets; return;}

if(s[0]=='*'||s[0]=='/')

{err_code=few_operands; return;}

for(i; i<l; i++)

{

if(s[i]=='(')

{

if(i>0&&operand_true(s[i-1]))

{err_code=few_operators; return;}

if(s[i+1]=='*'||s[i+1]=='/'||s[i+1]==')')

{err_code=few_operands; return;}

sk++; continue;

}

if(s[i]==')')

{ if((i>0)&&(s[i-1]=='*'||s[i-1]=='+'||s[i-1]=='-'||s[i-1]=='/'))

{err_code=few_operands; return;}

if(operand_true(s[i+1])||s[i+1]=='(')

{err_code=few_operators; return;}

sk--; continue;

}

if(s[i]=='*'||s[i]=='/'||s[i]=='+'||s[i]=='-')

{rang++; continue;}

if(operand_true(s[i]))

{

while (operand_true(s[++i]));

i--;

rang--;

}

else

{

err_code=bad_operands;

return;

}

}

s[i]='\0';

if(rang>-1) {err_code=few_operands; return;}

if(rang<-1) {err_code=few_operators; return;}

if(sk>0) {err_code=few_brackets; return;}

if(sk<0) {err_code=much_brackets; return;}

}

//--------------------------------------------------------------------------

 

void Stack::revers_before()

{

int l=strlen(s);

int i=l-1;

int j=0;

 

for(i;i>=0;i--)

{

if(s[i]=='(') sv[j++]=')';

else if(s[i]==')')sv[j++]='(';

else sv[j++]=s[i];

}

sv[j]='\0';

strcpy(s,sv);

//а теперь реверсируем операнды

int k;

for (i=0;i<l;i++)

{

if(operand_true(s[i]))

{

k=1;

while (operand_true(s[++i]))k++;

i--;

for(j=0;j<k;j++)

{s[i+1-k+j]=sv[i-j];}

}

}

}

//--------------------------------------------------------------------------

 

void Stack::revers_after()

{

int i=0;

int l=strlen(s);

int j=l-1;

 

for(j;j>=0;j--) sv[i++]=s[j];

sv[i]='\0';

strcpy(s,sv);

// а теперь реверсируем операнды

int k;

for (i=0;i<l;i++)

{

if(operand_true(s[i]))

{

k=1;

while (operand_true(s[++i]))k++;

i--;

for(j=0;j<k;j++)

{s[i+1-k+j]=sv[i-j];}

}

}

}

//-------------------------------------------------------------------------

 

void Stack::bspaces()

{

int l=strlen(s);

int i=0,j=0;

 

for(i;i<l;i++)

{

if(s[i]>='('&&s[i]<='+'||s[i]=='-'||s[i]=='/')

{ sv[j++]=s[i]; sv[j++]=' '; continue;}

else

{

sv[j++]=s[i];

while(operand_true(s[++i])==1&&s[i]!='\0')

sv[j++]=s[i];

sv[j++]=' ';

}

i--;

}

sv[j]='\0';

}

//--------------------------------------------------------------------------

 

void Stack::postfix()

{

int i=0,j=0,pr=0;

int l=strlen(s);

for(i;i<l;i++)

{

if(s[i]==' ') {sv[j++]=s[i]; continue;}

if(s[i]>='('&&s[i]<='+'||s[i]=='-'||s[i]=='/')

{

switch(s[i])

{

case '(':

{

if(!t1) {first1(s[i]);}

else {push1(s[i]);}

break;

}

case '*':

case '/':

{

if(!t1) {first1(s[i]); break;}

pr=prioritet_stack();

if(pr==3||pr==1) {push1(s[i]); break;}

 

if(t1->c=='/') sv[j++]=pop1();

if(t1) {push1(s[i]); break;}

else {first1(s[i]); break;}

}

case '+':

case '-':

{

if(!t1) {first1(s[i]); break;}

pr=prioritet_stack();

if(pr==3) {push1(s[i]); break;}

else

{

while(pr<3&&t1)

{

sv[j++]=pop1();

if(t1) pr=prioritet_stack();

}

}

if(t1) {push1(s[i]); break;}

else {first1(s[i]); break;}

}

case ')':

{

pr=prioritet_stack();

while(pr!=3)

{

sv[j++]=pop1();

pr=prioritet_stack();

}

sv[j]= pop1();

}

}

}

else {sv[j++]=s[i]; continue;}

}

if(t1){ while(t1) sv[j++]=pop1();}

sv[j]='\0';

strcpy(s,sv);

}

//-------------------------------------------------------------------------

float Stack::calc()

{

int i=0,j=0,l=strlen(s);

char sc[10];

float a,b;

for(i;i<l;i++)

{

if(s[i]==' ') continue;

else

if(s[i]=='+'||s[i]=='-'||s[i]=='*'||s[i]=='/')

{

a=pop2();

b=pop2();

switch(s[i])

{

case '+': {a=a+b; break;}

case '-': {a=b-a; break;}

case '*': {a=a*b; break;}

case '/': {a=b/a; break;}

}

if(!t2) {first2(a); }

else {push2(a); }

}

else

{

while(operand_true(s[i])&&s[i]!='\0')

{

sc[j++]=s[i];

i++;

}

sc[j]='\0';

a=atof(sc);

j=0;

if(!t2) {first2(a);}

else {push2(a); }

}

}

return pop2();

}

//-------------------------------------------------------------------------

В файле реализации LR_5.cpp модуля LR_5 разместим обработчики событий – создание формы и щелчки на разделах меню Новое, Преобразование, Преобразование и вычисление, Выход с именами соответственно FormCreate, N2Click, N3Click, N4Click, N6Click. Заметим, что обработчик FormCreate можно вызвать двойным щелчком на форме.

 

Файл реализации LR_5.cpp модуля LR_5

//---------------------------------------------------------------------------

 

#include <vcl.h>

#pragma hdrstop

 

#include "LR_5.h"

#include "f_5.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm1 *Form1;

//---------------------------------------------------------------------------

AnsiString

S1="В выражении есть неверные операнды! Проверьте правильность записи.",

S2="В выражении не хватает скобки! Проверьте правильность записи.",

S3="В выражении лишние скобки! Проверьте правильность записи.",

S4="В выражении недостаточно операндов! Проверьте правильность записи.",

S5="В выражении недостаточно знаков операций! Проверьте правильность записи.";

//---------------------------------------------------------------------------

void Stack::out_err_code()

{ switch(err_code)

{

case bad_operands: {ShowMessage(S1); break;}

case few_brackets: {ShowMessage(S2); break;}

case much_brackets: {ShowMessage(S3); break;}

case few_operands: {ShowMessage(S4); break;}

case few_operators: {ShowMessage(S5); break;}

};

}

//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)

: TForm(Owner)

{

}

//---------------------------------------------------------------------------

Stack S;

void __fastcall TForm1::FormCreate(TObject *Sender)

{

Edit1->Text="";

Edit2->Text="";

Edit3->Text="";

Edit4->Text="";

Edit5->Text="";

Edit6->Text="";

Edit7->Text="";

Edit8->Text="";

}

//--------------------------------------------------------------------------

void __fastcall TForm1::N2Click(TObject *Sender)

{

Edit1->Text="";

Edit2->Text="";

Edit3->Text="";

Edit4->Text="";

Edit5->Text="";

Edit6->Text="";

Edit7->Text="";

Edit8->Text="";

Edit1->SetFocus();

}

//---------------------------------------------------------------------------

void __fastcall TForm1::N3Click(TObject *Sender)

{

Edit2->Text="";

Edit3->Text="";

Edit4->Text="";

Edit5->Text="";

Edit6->Text="";

Edit7->Text="";

Edit8->Text="";

S.Stack_init();

S.s=(Edit1->Text+'\0'+'\0').c_str();

S.check();

if(S.err_code==all_true)

{

Edit2->Text=S.s;

S.bspaces();

S.s=S.sv;

Edit5->Text=S.s;

S.postfix();

Edit3->Text=S.s;

S.s=(Edit5->Text+'\0'+'\0'+'\0').c_str();

S.revers_before();

Edit6->Text=S.s;

S.postfix();

Edit7->Text=S.s;

S.revers_after();

Edit4->Text=S.s;

}

else

S.out_err_code();

}

//---------------------------------------------------------------------------

void __fastcall TForm1::N4Click(TObject *Sender)

{

Edit2->Text="";

Edit3->Text="";

Edit4->Text="";

Edit5->Text="";

Edit6->Text="";

Edit7->Text="";

Edit8->Text="";

S.Stack_init();

S.s=(Edit1->Text+'\0'+'\0').c_str();

S.check();

if(S.err_code==all_true)

{

Edit2->Text=S.s;

S.bspaces();

S.s=S.sv;

Edit5->Text=S.s;

S.postfix();

Edit3->Text=S.s;

S.s=(Edit5->Text+'\0'+'\0'+'\0').c_str();

S.revers_before();

Edit6->Text=S.s;

S.postfix();

Edit7->Text=S.s;

S.revers_after();

Edit4->Text=S.s;

S.s=(Edit3->Text+'\0'+'\0'+'\0').c_str();

float result=S.calc();

Edit8->Text=FloatToStr(result);

}

else

S.out_err_code();

}

//---------------------------------------------------------------------------

void __fastcall TForm1::N6Click(TObject *Sender)

{

exit(0);

}

//---------------------------------------------------------------------------

Подробно остановимся на использовании новых интерфейсных компонентов среды:ImageListсписок изображений, ActionList - диспетчер действий, ToolBarинструментальная панель. Эти компоненты необходимы в технологии программирования, использующей диспетчеризацию действий.

Здесь программирование начинается с составления списка действий, которые будут доступны пользователю через разделы меню, инструментальные панели, кнопки и другие элементы управления. При программировании этот список реализуется в данном случае компонентомActionList, обеспечивающим диспетчеризацию действий. Редактор диспетчера действийActionList позволяет сформировать список действий, написать обработчики (если их еще нет), выполняющие задуманные действия, задать основные свойства будущих интерфейсных элементов – пиктограммы, надписи, быстрые кнопки, тексты подсказок и т.п.

После того, как список действий создан, формируют полосы действий. Это полосы, на которых располагаются интерфейсные компоненты действий – полоса главного меню и инструментальные панели. В нашем случае – полоса главного меню уже создана. При использовании диспетчера действийActionList полосы действий добавляют на форму в виде отдельных компонентов, создают на них инициаторы действий (разделы меню, быстрые кнопки), а затем связывают инициаторы с соответствующими действиями из списка диспетчера действийActionList. При таком связывании свойства, заложенные в действия, автоматически передаются интерфейсным компонентам.

Интерфейсные компоненты действий обычно должны содержать поясняющие их изображения. Изображения собираются в списке изображений – компоненте ImageList. Для нестандартных действий (наш случай) изображения загружаются в ImageListпользователем. А для стандартных действий они загружаются автоматически по мере формирования списка в диспетчере действийActionList.

 



Дата добавления: 2020-10-14; просмотров: 288;


Поиск по сайту:

Воспользовавшись поиском можно найти нужную информацию на сайте.

Поделитесь с друзьями:

Считаете данную информацию полезной, тогда расскажите друзьям в соц. сетях.
Poznayka.org - Познайка.Орг - 2016-2024 год. Материал предоставляется для ознакомительных и учебных целей.
Генерация страницы за: 0.08 сек.