逆波兰计算器android源码简书,4.3外部变量与逆波兰计算器

本文详细介绍了C语言中外部变量与函数的作用,特别是它们如何在不同函数间共享数据。通过讲解getop函数和相关辅助函数的工作原理,阐述了如何处理输入的运算符和操作数。文章还探讨了栈的概念,如何使用push和pop函数来存储和检索数值。整个计算器程序的设计思路和实现细节被逐步展开,适合有一定C语言基础的读者深入理解程序设计。
摘要由CSDN通过智能技术生成

C语言程序可以看成由一系列的外部对象构成,这些外部对象可能是变量或函数。形容词external与internal是相对的。internal用于描述定义在函数内部的函数参数及变量。外部变量定义在函数之外可以在其他函数中使用。C语言不允许在函数中定义其他函数。外部变量永久存在,自动变量在退出函数消失。互不调用对方并且需要共享数据的两个函数,最好还是用外部变量。

书上说这个计算器程序的实现很简单,但是感觉是相对而言的,当时看这个的时候由于基础有限,看的还是比较难受的,但是当看到后面基础牢了点就好很多,现在来看这个确实是比较简单的一个程序,每个函数负责一个功能,而这些函数并不复杂,难的是想通其中的关键部分。

主要设计思路在书里这也不在多说。

逆波兰计算器

这个计算器例子我想了很长时间怎么解释,从哪部分开写,最后还是不想了,从头到后来吧。

定义函数时 push前面的void声明表示psh函数不返回任何值,括号里的double表示他要处理双精度浮点数类型的参数,pop的double声明表示他返回double类型的数值,但是没有任何附带参数。

首先看getop函数,用于获取下一个运算符或操作数。

这里又需要先说一下getch函数和ungetch函数

这两个函数想明白比较简单,想理解有那么一点复杂。

getch函数

返回一个值这个值有可能是在缓冲区也有可能是直接getchar获取,首先用一个外部变量bufp当做缓冲区的下标,因为两个函数修需要共享并且不互相调用,所以需要用到外部变量。

还有就是把buf当成缓冲区。

这个函数直接返回数值。条件判断式的值就是其返回值。

用一个条件表达式,判断buf缓冲区是否有字符存在。如果有则判断式的值为buf数组的第bufp个元素,如果buf数组没有字符存在则直接用getchar读取字符。然后将值返回。

return (bufp > 0) ? buf[--bufp] : getchar();

然后是ungetch函数。

这个函数将字符压入缓冲区。如果超过最大值则报警。

如果超过最大值则打印报警字符串。

if (bufp >= BUFSIZE)

printf("ungetch: too many characters\n");

不超过就直接将字符存入缓冲区buf数组。

buf[bufp++] = c;

再继续看getop函数。

跳过空白符,这里会将第0位元素保留为空白符(求指正)。

这里的保留为空白符是因为如果首位就是数字的话,还是需要保留的.因为首位是数字.s[0]就被赋值成数字了.

然后就会覆盖后面的空白符.

while ((s[0] = c = getch()) == ' ' | c == '\t')

;

然后将第1位元素置为‘\0’

s[1] = '\0'; 这里会把数组s变成一个只有一个空白符和结束符的数组。

之后是判断部分,首先判断是不是数,如果不是数并且不是小数点则将当前的字符返回给主函数main,让主函数去判断解决方法。

if (!isdigit(c) && c != '.')

return c;

接下来的将i赋值为0。

i = 0;

然后是收集整数部分,这里是将整数部分直接存入数组s中,这里的++i是前自增运算,先自增之后才参与赋值运算(这里最开始他的值是1,我做过测试,但是也不能保证肯定,希望有人指正。)

如果下标是1开始的话,那么之前的空格就会被留下了。(虽然留下也没什么atof函数我记得也会跳过空白符)

将整数部分的数收集到数组s中。

if(isdigit(c))

while (isdigit(s[++I] = c = getch()))

;

然后是碰到小数点,继续以同样的方式收集到数组s中。这里的i依然是先自增,目的是跳过的整数部分的最后一位。

if (c == '.')

while (isdigit(s[++i] = c =getch()))

;

最后将结束符'\0'加入数组s中。

s[i] = '\0';

然后继续判断,数值读取到最后还没到EOF文件结束符的话,那么需要将最后读入的这个字符放入缓冲区(原因书上写了,无法判断下一个字符到底是不是对程序有用的字符,只能先读取之后再看,所以如果不需要的话就需要将其放入缓冲区)

if (c != EOF)

ungetch(c);

然后都运行到这里了,就需要向主函数返回一个读取的是数的信号,

return NUMBER;

函数既然写这么多了,那就继续把剩下的两个比较简单和函数写完吧。

push函数。

作用就是将参数放入一个数组(栈)中。原理同上面的buf一样。如果不超过栈的最大值那么就将参数f放入到栈中。用变量sp记录栈顶的位置。

if (sp < MAXVAL)

val[sp++] = f;

如果超过最大值则显示错误报告。

else

printf("error: stack full, can't push %g\n", f);

pop函数就是将栈顶的元素取出变成返回主函数的值,就是说把pop函数当做栈顶的值。

if (sp > 0)

return val[--sp];

之后依然是错误报告,并且返回值为0.0。

之后进入主函数。

先定义变量type,用于确定字符是何种类型。op2用于直接指定运算顺序。数组s[MAXOP]需要运算的数。宏MAXOP是操作数或运算符的最大长度(100)。宏NUMBER也是一个用于判断类型。

int type;

double op2;

s[MAXOP];

直接用大循环判断当前字符的类型。之后就是通过switch语句进行分类操作,类型是什么就执行什么样的操作。,这里书上写的比较详细而且没什么难度,代码还很长久不直接写上来了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值