Язык Си - вопрос №274743

Помогите с задачей на языке Си.Дано целочисленное арифметическое выражение, записанное как строка, в десятичной системе счисления. Проверить правильность записи и вычислить значение этого выражения. Выражение записывается без скобок, операции выполняются в порядке их следования.Буду благодарен

Ответы

/* Это модуль содержит простой синтаксический анализатор,
который не распознает переменные.
*/

#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>

#define DELIMITER 1
#define VARIABLE 2
#define NUMBER 3

extern char *prog; /* содержит анализируемое выражение */
char token[80];
char tok_type;

void eval_exp(double *answer), eval_exp2(double *answer);
void eval_exp3(double *answer), eval_exp4(double *answer);
void eval_exp5(double *answer), eval_exp6(double *answer);
void atom(double *answer);
void get_token(void), putback(void);
void serror(int error);
int isdelim(char c);

/* Точка входа анализатора. */
void eval_exp(double *answer)
{
get_token();
if(!*token) {
serror(2);
return;
}
eval_exp2(answer);

if(*token) serror(0); /* последней лексемой должен быть нуль */
}

/* Сложение или вычитание двух слагаемых. */
void eval_exp2(double *answer)
{
register char op;
double temp;

eval_exp3(answer);
while((op = *token) == '+' || op == '-') {
get_token();
eval_exp3(&temp);
switch(op) {
case '-':
*answer = *answer — temp;
break;
case '+':
*answer = *answer + temp;
break;
}
}
}

/* Умножение или деление двух множителей. */
void eval_exp3(double *answer)
{
register char op;
double temp;

eval_exp4(answer);
while((op = *token) == '*' || op == '/' || op == '%') {
get_token();
eval_exp4(&temp);
switch(op) {
case '*':
*answer = *answer * temp;
break;
case '/':
if(temp == 0.0) {
serror(3); /* деление на нуль */
*answer = 0.0;
} else *answer = *answer / temp;
break;
case '%':
*answer = (int) *answer % (int) temp;
break;
}
}
}

/* Возведение в степень */
void eval_exp4(double *answer)
{
double temp, ex;
register int t;

eval_exp5(answer);

if(*token == '^') {
get_token();
eval_exp4(&temp);
ex = *answer;
if(temp==0.0) {
*answer = 1.0;
return;
}
for(t=temp-1; t>0; --t) *answer = (*answer) * (double)ex;
}
}

/* Умножение унарных операторов + и -. */
void eval_exp5(double *answer)
{
register char op;

op = 0;
if((tok_type == DELIMITER) && *token=='+' || *token == '-') {
op = *token;
get_token();
}
eval_exp6(answer);
if(op == '-') *answer = -(*answer);
}

/* Вычисление выражения в скобках. */
void eval_exp6(double *answer)
{
if((*token == '(')) {
get_token();
eval_exp2(answer);
if(*token != ')')
serror(1);
get_token();
}
else
atom(answer);
}

/* Получение значения в скобках. */
void atom(double *answer)
{
if(tok_type == NUMBER) {
*answer = atof(token);
get_token();
return;
}
serror(0); /* иначе синтаксическая ошибка в выражении */
}

/* Выражение лексемы во входной поток. */
void putback(void)
{
char *t;

t = token;
for(; *t; t++) prog--;
}

/* Отображение сообщения об ошибке. */
void serror(int error)
{
static char *e[]= {
«Синтаксическая ошибка»,
«Несбалансированные скобки»,
«Нет выражения»,
«Деление на нуль»
};
printf("%s\n", e[error]);
}

/* Возврат очередной лексемы. */
void get_token(void)
{
register char *temp;

tok_type = 0;
temp = token;
*temp = '\0';

if(!*prog) return; /* конец выражения */
while(isspace(*prog)) ++prog; /* пропустить пробелы,
символы табуляции и пустой строки */

if(strchr("+-*/%^=()", *prog)){
tok_type = DELIMITER;
/* перейтик следующему символу */
*temp++ = *prog++;
}
else if(isalpha(*prog)) {
while(!isdelim(*prog)) *temp++ = *prog++;
tok_type = VARIABLE;
}
else if(isdigit(*prog)) {
while(!isdelim(*prog)) *temp++ = *prog++;
tok_type = NUMBER;
}

*temp = '\0';
}

/* Возвращение значения ИСТИНА, если с является разделителем. */
int isdelim(char c)
{

if(strchr(" +-/*%^=()", c) || c==9 || c=='\r' || c==0)
return 1;
return 0;
}

char *prog;
void eval_exp(double *answer);

int main(void)
{
double answer;
char *p;

p = (char *) malloc(100);
if(!p) {
printf(«Ошибка при выделении памяти.\n»);
exit(1);
}

/* Обработка выражений до ввода пустой строки. */
do {
prog = p;
printf(«Введите выражение: „);
gets(prog);
if(!*prog) break;
eval_exp(&answer);
printf(“Результат: %.2f\n», answer);
} while(*p);

return 0;
}

 

Проверила, работает

Источник и описание 

lord-n.narod.ru/download/books/walla/programming/Spr_po_C/24/2404.htm

Еще один источник

 www.bhv.ru/books/get_pdf_data.php?id=183103

Буду благодарна, если отметите 

22.05.12

Еva

от 100 p.
Читать ответы
Посмотреть всех экспертов из раздела Учеба и наука > Информатика
Пользуйтесь нашим приложением Доступно на Google Play Загрузите в App Store