中缀计算器
基本运算已经完成,可以进行 + - × / 幂 以及负数计算, 可以正确判断圆括号的优先级,以及表达式的合法性。程序代码:
#include <stdio.h> #include "Stack.h" #include <ctype.h> #include <string.h> #include <stdlib.h> #include <setjmp.h> #include <math.h> typedef char OperatorType; typedef double OpType; int getoperand( void ); void Introduce( void ); void Help( void ); void Precision( int *precision ); void Plus( OperatorType ch ); void Product( OperatorType ch ); void Power( OperatorType ch ); void LeftParenthes( OperatorType ch ); void RightParenthes( void ); void Factorial( OperatorType ch ); void Compute( OperatorType ch ); void End( int precision ); void ErrorProcess( void ); jmp_buf restart; int main( void ) { int ch; int precision; precision = 2; Introduce(); setjmp( restart ); while( EOF != ( ch = getoperand() ) ) { switch( ch ) { case '+': case '-': Plus( ch ); break; case '*': case '/': case '%': Product( ch ); break; case '^': Power( ch ); break; case '!': Factorial( ch ); break; case '(': LeftParenthes( ch ); break; case ')': RightParenthes(); break; case '\n': End( precision ); break; case 'H': case 'h': Help(); getchar(); break; case 'j': case 'J': Precision( &precision ); break; case ' ': break; default: ErrorProcess(); break; } } return 0; } void Introduce( void ) { printf( "这是一个提供加、减、乘、除、阶乘、幂、模运算的计算器。\n" "输入的任一表达式以回车结束。\n" "如果表达式最后的运算符为右(圆、方、花)括号,则该括号可以省略。\n" "输入h查看帮助。\n"); } void Help( void ) { printf( "加运算符:+\n" "减运算符:-\n" "乘运算符:*\n" "除运算符:/(除数不可以为0)\n" "幂运算符:^(Shift + 6)(例如:3^2 或 3^2.5)\n" "阶乘运算符:!(Shift + 1)(例如:3!)\n" "模运算符:%%(Shift + 5)(例如:3%%2)\n" "调节精度: j\n" ); printf( "\n注意:\n 阶乘很容易造成溢出,请小心使用这个运算符!\n" " 阶乘溢出所得的值将为0。\n" " 阶乘运算符的操作数必须是整数!\n\n" ); } MAKE_STACK( OperatorType, _Operator, 128 ) MAKE_STACK( OpType, _Op, 128 )//操作数简写为Op #define MAXSIZE 128 int getoperand( void ) { char Src[ MAXSIZE ]; int ix, ch; for( ix = 0; MAXSIZE - 1 > ix && EOF != ( ch = getchar() ) && !isspace( ch ); ++ix ) { if( isdigit( ch ) || '.' == ch ) Src[ ix ] = ch; else if( '-' == ch ) { if( 0 == ix ) Src[ ix ] = ch; else break; } else break; } if( '{' == ch || '[' == ch ) ch = '('; else if( '}' == ch || ']' == ch ) ch = ')'; Src[ ix ] = '\0'; if( 1 == ix && '-' == Src[ 0 ] ) return Src[ 0 ]; if( 0 < ix ) Posh_Op( atof( Src ) ); return ch; } void End( int precision ) { OperatorType t; OpType temp; if( Is_Empty_Op() && Is_Empty_Operator() ) return; while( !Is_Empty_Operator() ) { if( '(' != ( t = Top_Operator() ) ) Compute( t ); Pop_Operator(); } temp = Top_Op(); Pop_Op(); if( Is_Empty_Op() ) printf("%.*lf\n\n", precision, temp ); else printf( "\n错误的表达式,数据已清空,请重新输入。\n" ); DeleteStack_Op(); } void Precision( int *precision ) { while( printf( "输入新的精度( 0 - 20 ):" ) ) { scanf( "%d", precision ); getchar(); if( 0 <= *precision && 20 >= *precision ) { printf( "精度设置为:%d\n", *precision ); break; } else printf( "精度范围错误,重新输入(精度范围为0 - 20)\n" ); } } void Plus( OperatorType ch ) { OperatorType t; if( Is_Empty_Op() ) ErrorProcess(); if( !Is_Empty_Operator() && '(' != ( t = Top_Operator() ) ) { Compute( t ); Pop_Operator(); } Posh_Operator( ch ); } void Product( OperatorType ch ) { OperatorType t; if( Is_Empty_Op() ) ErrorProcess(); if( !Is_Empty_Operator() ) if( '*' == ( t = Top_Operator() ) || '/' == t || '^' == t || '%' == t ) { Pop_Operator(); Compute( t ); } Posh_Operator( ch ); } void Power( OperatorType ch ) { OperatorType t; if( Is_Empty_Op() ) ErrorProcess(); if( !Is_Empty_Operator() && '^' == ( t = Top_Operator() ) ) { Pop_Operator(); Compute( t ); } Posh_Operator( ch ); } void Factorial( OperatorType ch ) { Compute( ch ); } void LeftParenthes( OperatorType ch ) { Posh_Operator( ch ); } void RightParenthes( void ) { OperatorType t; while( !Is_Empty_Operator() && '(' != ( t = Top_Operator() ) ) { Pop_Operator(); Compute( t ); } Pop_Operator(); } void Compute( OperatorType ch ) { OpType op1, op2; int i; int product; static int Lilisi = 0; if( !Is_Empty_Op() ) { op1 = Top_Op(); Pop_Op(); } else ErrorProcess(); if( !Is_Empty_Op() && '!' != ch ) { op2 = Top_Op(); Pop_Op(); } else if( Is_Empty_Op() && '!' != ch ) ErrorProcess(); switch( ch ) { case '+': Posh_Op( op1 + op2 ); break; case '-': Posh_Op( op2 - op1 ); break; case '*': Posh_Op( op1 * op2 ); break; case '/': if( 0 == op1 ) { if( 0 == Lilisi++ ) { printf( "\n假设你有0块饼干,要将它分给0个朋友,每个朋友能分到几块饼干?\n" "你看,这个问题没有半毛钱意义。\n" "你的朋友会很难过,因为没有饼干吃.\n" "你也会很难过,因为你一个朋友也没有。\n"); } printf( "\n除数不能为0!\n" ); ErrorProcess(); } Posh_Op( op2 / op1 ); break; case '%': if( 0 == op1 ) ErrorProcess(); Posh_Op( fmod( op2, op1 ) ); break; case '^': Posh_Op( pow( op2, op1 ) ); break; case '!': if( 0 > op1 ) ErrorProcess(); for( i = 1, product = 1; i <= ( int )op1; ++i ) product *= i; Posh_Op( product ); break; default: break; } } void ErrorProcess( void ) { DeleteStack_Op(); DeleteStack_Operator(); while( '\n' != getchar() ) ; printf("\n错误的表达式,数据已清空,重新输入!\n"); longjmp( restart, 1 ); }
程序代码:
/* Stack.h */ #define MAKE_STACK( Stack_type, Suffix, size ) \ static Stack_type Stack##Suffix[ size ]; \ static int TopLx##Suffix = -1; \ \ int \ Is_Empty##Suffix( void ) \ { \ return -1 == TopLx##Suffix; \ } \ \ int \ Is_Full##Suffix( void ) \ { \ return size - 1 == TopLx##Suffix; \ } \ \ \ void \ Posh##Suffix( Stack_type value ) \ { \ Stack##Suffix[ ++TopLx##Suffix ] = value; \ } \ \ void \ Pop##Suffix( void ) \ { \ --TopLx##Suffix; \ } \ \ Stack_type \ Top##Suffix( void ) \ { \ return Stack##Suffix[ TopLx##Suffix ]; \ } \ \ void \ DeleteStack##Suffix( void ) \ { \ TopLx##Suffix = -1; \ }
[此贴子已经被作者于2017-5-29 19:26编辑过]