由《C程序设计语言》P64页与5-10练习题改编成
#include <stdio.h>
#include <ctype.h>
#define MAXLINE 100
#define NUMBER '0'//是数字的标志
/*逆波兰计算器*/
double atoi(char *s);
void push(double number);
double pop();
char getop(char *s, char *str);
double stack[MAXLINE];
int k = 0;//栈中指针的位置
int main(int argc, char *argv[])
{
int i;
double num1 = 0, num2 = 0;
char c, s[MAXLINE];
for(i = 1; i < argc; i++)
{
*s = NULL;
switch(c = getop(s, argv[i])){
case NUMBER://说明是数字,将数字放入栈中存储
printf("%lf %s\n", atoi(s), s);
push(atoi(s));
// printf("%lf %s\n", atoi(s), s);
break;
case '+':
num1 = pop();
num2 = pop();
printf("%lf, %lf\n", num1, num2);
push(num1 + num2);
break;
case '*':
num1 = pop();
//printf("%lf\n", num1);
num2 = pop();
printf("%lf, %lf\n", num1, num2);
push(num2 * num1);
break;
case '-':
num1 = pop();
num2 = pop();
printf("%lf, %lf\n", num1, num2);
push(num2 - num1);
break;
case '/':
num1 = pop();
//printf("%lf\n", num1);
num2 = pop();
printf("%lf, %lf\n", num1, num2);
if(num1 == 0){
printf("the number is illegal!");
}
else
push(num2 / num1);
break;
default:
printf("the char is illegal!");
break;
}
}
printf("%.4g\n", pop());
return 0;
}
//将字符串s转换为对应数字
double atoi(char *s)
{
double sum = 0, flag = 1;//先将double型数字记录成整型,然后再通过flag转换为double
int sign = 0;//记录符号
/*while(*s == ' ' || *s == '\t')
s++;*/
sign = (*s == '-')? -1: 1;
if(*s == '-' || *s == '+')
s++;
/*if(!isdigit(*s) && *s != '.')
return 0;*/
while(isdigit(*s)){
sum = sum * 10 + (*s - '0');
s++;
}
if(*s == '.'){
sum = sum * 10 + (*s - '0');
s++;
flag *= 10.0;
}
sum = sign * sum / flag;
// printf("%lf\n", sum);
return sum;
}
//将数字放入栈中
void push(double number)
{
if(k == MAXLINE){
printf("the stack is full.\n");
return;
}
else
stack[k++] = number;
}
//将栈顶数字取出
double pop()
{
if(k == 0){
printf("the stack is empty.\n");
return 0;
}
else
return stack[--k];
}
//从str中获取下一个数字或运算符,保存在r字符串s中
char getop(char *s, char *str)
{
// int sign = 0;
while(*str == ' ' || *str == '\t')
str++;
//sign = (*str == '-')? -1: 1;
if((*str == '-' && *(str+1) != '\0') || (*str == '+' && *(str+1) != '\0')){
*s++ = *str;
str++;
}
else if(!isdigit(*str) && *str != '.')
return *str;
while(isdigit(*str)){
*s++ = *str++;
}
if(*str == '.')
*s++ = *str++;
while(isdigit(*str)){
*s++ = *str++;
}
*s = '\0';
return NUMBER;
}
注意,程序应该也可以计算带负数的式子。这一点我在第一遍写出来代码后,不能实现该功能,后来才想起来。所以要注意容易被遗忘的条件。