1. Пользуйтесь тегами кода. - [code] ... [/code] 2. Точно указывайте язык, название и версию компилятора (интерпретатора). 3. Название темы должно быть информативным. В описании темы указываем язык!!!
Хочу написать програмку-калькулятор (по книге Кернигана и Ритча). Суть простая: вводится выражение в форме обратной польской нотации, оно вычисляется и выводится результат.
Программу разбил на функции:
1) GetLine - получение строки (работает нормально). 2) calculate - вычисление и получение результата, вот тут проблема, при входе в функцию появляется та самая ошибка сегментирования. 3) getop - получение следующего элемента из строки. (тоже самое). 4) pop и push - работа со стеком. (работают тоже не правильно, но по крайней мере из-за них программа не вылетает).
Компилятор GCC.
calculate(Показать/Скрыть)
double calculate (char expr[]) {
char type; double op2;
printf ("Начало вычисления"); // я это специально здесь поставил, но до этого места даже не доходит.
while ( ( type = getop(expr) ) != EOE ) switch ( type ) { case NUMBER: ; break; case '+': push (pop() + pop()); break; case '-': op2 = pop(); push (pop() - op2); break; case '*': push (pop() * pop()); break; case '/': if ( (op2 = pop()) != 0.0) push (pop() / op2); else printf ("Ошибка: деление на нуль.\n"); break; default: printf ("Ошибка: неизвестная операция.\n"); break; }
return pop();
}
getop(Показать/Скрыть)
int getop (char expr[]) {
static int i; /* getop будет возвращать найденную операцию или NUMBER если найдено число, потом после того как calculate выполнит необходимые действия работа будет продолжена там, где остановилась.*/ int j; char op[10];
, то есть, заносятся значения в стек правильно. Но вот теперь еще одна проблема: у тебя i вылетает за пределы строки, и возвращаться из функции будет уже не "+", а мусор, у меня это был пробел, потому что завершающий '\0' находится в 7-ом символе (начиная от 0)... Может, ты еще что-то в коде поменял, я не знаю, все, что ты написал - я изменил...
Я, в принципе, могу тебе и так сказать, где ты ошибся: При возвращении знака операции надо сначала запомнить тот символ, который лежит в expr[ i ], потом увеличить i, и только потом возвращать символ. Запомненный, естественно...
else if ( expr[ i ] == '+' || expr[ i ] == '-' || expr[ i ] == '*' || expr[ i ] == '/' ) { char ch = expr[ i ]; i += 2; return ch; }
, хотя я бы еще вместо того, чтоб все время тягать такие длинные проверки (символ сравнивать с несколькими константами), делал бы так:
else if (strchr("+-*/", expr[ i ])) { ... }
Цитата
Т.е. если я захочу сохранить значение переменной после выхода из функции я как-то ещё поступить? Как?
Для начала эту переменную надо инициализировать (static int i = 0;). Потому что инициализация статической переменной производится на этапе компиляции, и больше - никогда (при входе в функцию переменная обнуляться не будет).