重温C语言(1)----计算算术表达式的值
《C程序设计语言》练习题 5-10
编写程序 expr,计算从命令行输入的逆波兰表达式的值,其中每个运算符或操作数用一个单独的参数表示。例如,命令
expr 2 3 4 + *
计算表达式2x(3+4)的值
算法实现
getfloat.c:
// getfloat.c
#include<stdio.h>
#include<ctype.h>
int getfloat(char* str, double* store)
{
while (isspace(*str))
str++;
int ch, sign;
double power = 1.0;
ch = *str++;
sign = ch == '-' ? -1 : 1;
if (ch == '+' || ch == '-') {
ch == *str++;
}
for (*store == 0.0; isdigit(ch); ch = *str++) {
*store = *store*10.0 + ch - '0';
}
if (ch == '.') {
ch=*str++;
}
for (; isdigit(ch); ch = *str++) {
*store = *store*10.0 + ch - '0';
power *= 10.0;
}
if (ch == 0 || isspace(ch) || ch == EOF) {
//如果不能继续读取数字,那么跳出的原因必须是 ch==0 || isspace(ch) || ch==EOF
*store /= power;
*store *= sign;
return 1;
}
else {
return -1;
}
}
expr.c:
//expr.c
#include<stdio.h>
#include<ctype.h>
#define MAX_NUM 100
double stack[MAX_NUM];
extern int getfloat(char* str,double*);
int main(int argc, char* argv[])
{
if (argc < 2) {
printf("usage: expr num1 num2 operator ...\n");
return 1;
}
else {
int stackp = 0;
int ch = 0;
double num1, num2, ans;
while (--argc >= 1) {
ch = (*++argv)[0];
if (ch == '-'){
if (!isdigit(ch = (*argv)[1])) {
//是负号
if (stackp >= 2) {
num2 = stack[--stackp];
num1 = stack[--stackp];
stack[stackp++] = num1 - num2;
continue;
}
else {
printf("Error: at least two numbers are needed before operator '-'\n");
return -1;
}
}
}
if (isdigit(ch)) {
if (stackp < 0) {
printf("stack is underflowed!\n");
return -2;
}
else if (stackp >= MAX_NUM) {
printf("stack is overflowed!\n");
return -3;
}
else if (getfloat(*argv, &stack[stackp++]) == -1) {
printf("wrong argument to get number: %s\n", *argv);
return -4;
}
}
else if (ch == '+'||ch=='*'||ch=='/'||ch=='%') {
if (stackp >= 2) {
num2 = stack[--stackp];
num1 = stack[--stackp];
switch (ch) {
case '+':
ans = num1 + num2;
break;
case '*':
ans = num1*num2;
break;
case '/':
if (num2 == 0.0) {
printf("error zero divisor: %f / %f\n", num1, num2);
return -5;
}
ans = num1 / num2;
break;
case '%':
ans = (int)num1%(int)num2;
break;
}
stack[stackp++] = ans;
}
else {
printf("Error: at least two numbers are needed before operator '%c'\n",ch);
return -6;
}
}
else {
printf("wrong arguments for %c,usage: expr num1 num2 operator ...\n", ch);
return -7;
}
}
if (stackp == 1) {
printf("%.4f\n", stack[0]);
}
else {
printf("the format of input is wrong!\n");
}
}
return 0;
}
重温C语言(1)----计算算术表达式的值的更多相关文章
- 【算法】E.W.Dijkstra算术表达式求值
算术表达式求值 我们要学习的一个栈的用例同时也是展示泛型的应用的一个经典例子,就是用来计算算术表达式的值,例如 ( 1 + ( ( 2 + 3 ) * ( 4 * 5 ) ) ) 如果将4乘以5,把3 ...
- 栈的一个实例——Dijkstra的双栈算术表达式求值法
Dijkstra的双栈算术表达式求值法,即是计算算术表达式的值,如表达式(1 + ( (2+3) * (4*5) ) ). 该方法是 使用两个栈分别存储算术表达式的运算符与操作数 忽略左括号 遇到右括 ...
- 利用栈实现算术表达式求值(Java语言描述)
利用栈实现算术表达式求值(Java语言描述) 算术表达式求值是栈的典型应用,自己写栈,实现Java栈算术表达式求值,涉及栈,编译原理方面的知识.声明:部分代码参考自茫茫大海的专栏. 链栈的实现: pa ...
- OpenJudge计算概论-简单算术表达式求值
/*===================================== 简单算术表达式求值 总时间限制: 1000ms 内存限制: 65536kB 描述 2位正整数的简单算术运算(只考虑整数运 ...
- Dijkstra的双栈算术表达式求值算法
这次来复习一下Dijkstra的双栈算术表达式求值算法,其实这就是一个计算器的实现,但是这里用到了不一样的算法,同时复习了栈. 主体思想就是将每次输入的字符和数字分别存储在两个栈中.每遇到一个单次结束 ...
- 算法手记(2)Dijkstra双栈算术表达式求值算法
这两天看到的内容是关于栈和队列,在栈的模块发现了Dijkstra双栈算术表达式求值算法,可以用来实现计算器类型的app. 编程语言系统一般都内置了对算术表达式的处理,但是他们是如何在内部实现的呢?为了 ...
- 实现Linux下dc的功能,计算后缀表达式的值
提交测试截图和码云练习项目链接,实现Linux下dc的功能,计算后缀表达式的值 -将运算符写在两个操作数之后的表达式称为"后缀表达式",如上面的中缀表达式可转换为后缀表达式1 2 ...
- [Java]算术表达式求值之三(中序表达式转二叉树方案 支持小数)
Entry类 这个类对表达式的合法性进行了粗筛: package com.hy; import java.io.BufferedReader; import java.io.IOException; ...
- [Java]算术表达式求值之二(中序表达式转后序表达式方案,支持小数)
Inlet类,入口类,这个类的主要用途是验证用户输入的算术表达式: package com.hy; import java.io.BufferedReader; import java.io.IOEx ...
随机推荐
- 开源系统-edusoho在线教育
#部署 ```bash [root@localhost ~]# docker run --name edusoho -tid -p 9900:80 -e DOMAIN= ...
- (原创推荐文章)kerberos服务器端与客户端
#环境 两台装centos7的虚拟机即可. kerberos服务器端与客户端各一台 (本文档推荐使用Typora软件观看) # 1.kerberos服务器端配置 ## 1.1安装配置Kerberos ...
- 【实战】某项目SQL注入引发的思考
数据包: 测试参数:username,测试payload: ' ' or '1'='1 ' or '1'='2 响应结果都未发生任何变化,借助sqlmap测试,结果一样: 尝试在or前面进行简单的fu ...
- Fix the error in NeighboringCellInfo.java in CM10.1
1.error messenge: frameworks/base/telephony/java/android/telephony/NeighboringCellInfo.java:: error ...
- WPF 自定义ScrollViwer
ScrollViewer自定义样式 ScrollViewer在各种列表.集合控件中广泛使用的基础组建,先看看效果图: 如上图,ScrollViewer简单来说分两部分,一个横向的滚动条,一个垂直滚动条 ...
- JavaScript -- 定义二维数组
方法一:直接定义并且初始化,这种遇到数量少的情况可以用var _TheArray = [["0-1","0-2"],["1-1"," ...
- [Mysql]——备份、还原、表的导入导出
备份 1. mysqldump mysqldump备份生成的是个文本文件,可以打开了解查看. Methods-1 备份单个数据库或其中的几个表# mysqldump -u username -p'pa ...
- 把AspDotNetCoreMvc程序运行在Docker上-part2:修改容器以及发布镜像
在上一个part<把AspDotNetCoreMvc程序运行在Docker上-part1>,已经将成功将aspdotnetcore程序运行在两个不同的容器中,目前两个容器的内容完全相同,只 ...
- XAMPP环境的搭建
XAMPP是一个强大的集成软件包(什么是集成软件包?就是多个软件打包一起安装了,比如office办公软件包括了word.Excel.PPT) XAMPP包括了Apache,MySQL,PHP,Perl ...
- OpenFileDialog 打开文件对话框
InitialDirectory 对话框的初始目录 Filter 要在对话框中显示的文件筛选器,例如,"文本文件(*.txt)|*.txt|所有文件(*.*)||*.*" Filt ...