中缀计算器
基本运算已经完成,可以进行 + - × / 幂 以及负数计算, 可以正确判断圆括号的优先级,以及表达式的合法性。
程序代码:#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编辑过]









~~~~

