token_value get_token(void);
// Ввод числа
void get_number(void);
// Ввод имени функции
void get_name(void);
// Вычисление полного выражения
double expr(void);
// Вычисление слагаемого
double term(void);
// Вычисление первичной части выражения
double prim(void);
// Вычисление значения функции
double function_value(void);
// Вывод сообщения об ошибке
double error(char *);
// Проверка на терминальный символ
int term_sym(char);
// Исправление ошибки клавишей BACKSPACE
void back_space(int *);
// Проверка дублирования знака операции
void dupl_oper_verify(char, char);
// Окно вывода сообщения
void message();
// Рамка окна
void ramka();
// Окно ввода выражения
void screen_input();
// Окно ввода ответа
void screen_output();
// Информация
void info();
// Организация меню
void menu(int n);
// Музыка при выходе
void sound_exit();
//Два на два
void dva_x_dva();
/*===============================Основная часть============================*/ void main()
FILE *help, *about; int m=1,loop=1,i,pr;
double x;
char s[255],key = -1,*put,*empty_str;
clrscr();
textbackground(0);
textcolor(15);
while(loop)
menu(m);
do
key = getch();
if (key==72 && m>1)
m--;
sound(220);
delay(50);
nosound();
;
if (key==80 && m<4)
m++;
while (key!=13);
switch(m)
case 1:
clrscr(); if((help=fopen(put="d:\\univer\\langs\\bc\\work\\Help.txt","r"))==NULL)
printf("Imposible open file %s!\n",put);
getch();
break;
return;
i=0;
while(!feof(help))
putchar(getc(help));
i++;
_setcursortype(_NOCURSOR);
case 2:
ramka();
screen_input();
screen_output();
message();
info();
dva_x_dva();
_setcursortype(_NORMALCURSOR);
gotoxy(6,4);
func_name = (char*) Malloc(5);
while (1)
get_token();
if (curr_tok == END) break;
if (curr_tok != PRINT && curr_tok != NEXT)
pr=printf("%f\n",expr());
if(pr!=0)
printf(" "
" ");
free(func_name);
case 3:
clrscr(); if((about=fopen(put="d:\\univer\\langs\\bc\\work\\Credits.txt","r"))==NULL)
while(!feof(about))
putchar(getc(about));
case 4:
sound_exit();
loop = 0;break;
default:
continue;
/*=========================Проверка нехватки памяти========================*/
void *Malloc(size_t size)
void *p;
if((p=malloc(size))==NULL)
printf(" No memory\n");
exit(1);
return p;
/*==================Функция синтаксического разбора выражения==============*/
token_value get_token()
char ch;
if ((ch = getch()) == ESC) return curr_tok = END;
while (ch == ' ');
switch(ch)
case ';':
putch(ch);
ps = '\x0';
return curr_tok = PRINT;
case '\r':
gotoxy(1,wherey()+1);
return curr_tok = NEXT;
case '*': case '/': case '+': case '-':
case '(': case ')': case '=': case '^':
dupl_oper_verify(ps, ch);
return curr_tok = ch;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': case '.':
ungetch(ch);
get_number();
return curr_tok = NUMBER;
if (isalpha(ch))
get_name();
return curr_tok = NAME;
error("Invalid symbol");
/*=====================Проверка дублирования знака операции================*/
void dupl_oper_verify(char ps, char ch)
if (ps=='*' || ps=='/' || ps=='+' || ps=='-' || ps=='^')
error("Operation is duplicated");
ch = ps;
else
if (ps=='*' || ps=='/' || ps=='+' || ps=='-' || ps=='^') ps = ch;
/*====================================Ввод числа===========================*/
void get_number()
char ch, dec_flag=0;
char *anum;
int i=0;
anum = (char*) Malloc(32);
ch=getch();
if (isdigit(ch))
*(anum+i) = ch;
if (ch == '.')
if (dec_flag) error("Second decimal point is forbidden");
dec_flag = 1;
if (ch == BACKSPACE) back_space(&i);
if (!term_sym(ch))
ch = BACKSPACE;
while (i < 31 && (isdigit(ch) || ch == '.' || ch == BACKSPACE));
anum[i] = '\x0';
number_value = _atold(anum);
free(anum);
/*=====================Проверка на терминальный символ=====================*/
int term_sym(char ch)
if (ch == '*' || ch == '/' || ch == '+' || ch == '-' ||
ch == '(' || ch == ')' || ch == '=' || ch == '^' ||
ch == ESC || ch == ';' || ch == '\r') return 1;
else return 0;
/*================Исправление ошибки клавишей BACKSPACE====================*/
void back_space(int *i)
if (i)
gotoxy(wherex()-1,wherey());
putch(' ');
i--;
/*========================Ввод имени функции==============================*/
void get_name()
int i=0, j;
ch = getch();
if (isalnum(ch))
*(func_name+i) = ch;
for (j = 0; j < 42 && strncmp(funcs+j,func_name,i); j += 6);
if (j >= 42)
error("Invalid function");
while (i < 5 && (isalnum(ch) || ch == BACKSPACE));
*(func_name+i) = '\x0';
function_number = j/6;
/*=====================Вычисление полного выражения========================*/
double expr()
double left = term();
while(1)
switch(curr_tok)
case PLUS:
left += term();
case MINUS:
left -= term();
if (curr_tok != RP)
// gotoxy(31,8);
gotoxy(23,8);
printf(" ");
return left;
/*===========================Вычисление слагаемого=========================*/
double term()
double left = prim();
case MUL:
left *= term();
case DIV:
float d = prim();
if (!d) return error("Division by zero");
left /= d;
case POWER:
left = pow(left,term());
/*==================Вычисление первичной части выражения===================*/
double prim()
case NUMBER:
return number_value;
case NAME:
return function_value();
return -prim();
case LP:
double e = expr();
if (curr_tok != RP) return error("Rigth parentsis expected");
return e;
case END:
return 1;
/*=====================Вычисление значения функции========================*/
double function_value()
switch(function_number)
case 0:
return sin(expr());
return cos(expr());
return log(expr());
return asin(expr());
return acos(expr());
case 5:
return E;
case 6:
return PI;
/*========================Вывод сообщения об ошибке========================*/
double error(char *s)
int sx, sy;
char *empty_str, *err_message;
err_message = (char*) Malloc(strlen(s)+29);
strcpy(err_message,s);
strcat(err_message,". Press any key to continue!");
empty_str = (char*) Malloc(strlen(s)+29);
memset(empty_str,' ',strlen(s)+28);
empty_str[strlen(s)+28] = '\x0';
sx = wherex();
sy = wherey();
gotoxy(16,22);
textcolor(10);
cprintf("%s",err_message);
sound(440);
delay(550);
cprintf("%s",empty_str);
gotoxy(sx,sy);
free(err_message);
free(empty_str);
/*==============================Окно сообщения============================*/
void message()
textcolor(RED);
gotoxy(15,21);
cprintf("-");
for(int x=16;x<70;x++)
gotoxy(15,22);
cprintf("|");
gotoxy(70,22);
gotoxy(15,23);
for(int x1=16;x1<70;x1++)
gotoxy(3,22);
cprintf("Message:");
/*==================================Рамка=================================*/
void ramka()
cprintf("=");
for(int x=2;x<80;x++)
for(int y=2;y<24;y++)
cprintf("|\n\b");
for(int x1=2;x1<80;x1++)
gotoxy(80,2);
for(int y1=2;y1<24;y1++)
gotoxy(80,y1);
/*=================================Окно ввода=============================*/
void screen_input()
gotoxy(5,3);
for(int x=6;x<76;x++)
gotoxy(5,4);
gotoxy(76,4);
gotoxy(5,5);
for(int x1=6;x1<76;x1++)
gotoxy(35,2);
cprintf("Input expression");
/*=================================Окно вывода=============================*/
void screen_output()
gotoxy(22,7);
for(int x=22;x<58;x++)
gotoxy(22,8);
gotoxy(59,8);
gotoxy(22,9);
for(int x1=22;x1<58;x1++)
gotoxy(39,6);
cprintf("Answer");
/*================================Информация===============================*/
void info()
gotoxy(13,11);
cprintf("Input expression, used +-*/()^ sin,cos,asin,acos,ln,pi,e");
gotoxy(22,12);
cprintf("Enter ; = output answer Esc exit");
/*====================================Меню================================*/
void menu(int n)
textcolor(3); gotoxy(31,9);
cprintf("Program calculator\n");
if (n == 1) textcolor(12); else
gotoxy(37,12);
cprintf("Help\n");
if (n == 2) textcolor(12); else
gotoxy(34,14);
cprintf("Calculator\n");
if (n == 3) textcolor(12); else
gotoxy(33,16);
cprintf("About author\n");
if (n == 4) textcolor(12); else
gotoxy(37,18);
cprintf("Exit\n");
/*===========================Музыка при выходе===========================*/
void sound_exit()
sound(659.3);
delay(310);
sound(784);
sound(721.65);
sound(495.9);
sound(587.3);
sound(513.65);
/*=================================Два на два=============================*/
void dva_x_dva()
textcolor(1);
gotoxy(32,15);
cprintf("---- ----");
gotoxy(34,16);
cprintf("-- --- -- ----");
gotoxy(32,17);
cprintf("-- - - -- ----");
gotoxy(32,18);
Страницы: 1, 2