《C++程序设计原理与实践》第六、七章整理

单词实现

为了从输入读取包括数字和运算符在内的表达式,我们需要采用“分词”的方法,首先需要引入“单词”。

单词(token)是表示可以看作一个单元的一个字符序列。在这里,每个单词需要记录其类型和值,即将单词表示为(kind, value)对,kind表示单词是一个数、运算符还是括号,若单词为一个数,value就表示其值。以下我们自定义Token类型,来储存这样的数据:

class Token{
	public:
		char kind;
		double value;
};

 可以这样定义:

Token t1;
t1.kind = '+';

Token t2;
t2.kind = '8';
t2.value = 3.14;

 除此之外,还有一种更加方便的方法,即利用构造函数来定义:

class Token{
	public:
		char kind;
		double value;
		Token(char ch);
		Token(char ch, double val);
};
Token::Token(char ch)
	:kind(ch), value(0)
	{
	}

Token::Token(char ch, double val)
	:kind(ch), value(val)
	{
	}

Token t1('+');
Token t2('8', 3.14);

Token(char ch)Token(char ch, double val)为构造函数。这里需要注意的几点是:

1. 构造函数名必须与类型名一致;

2. 只有在构造函数的初始化中才可以使用以冒号开始的特殊初始化语法;

3. 当我们定义了构造函数后,再使用Token t2; t2.kind = '8'; t2.value = 3.14;来定义就会出现错误。因为在Token类型中我们定义的两个构造函数都是有参数的,因此在定义时要么是只有kind值,要么是既有kind又有value,不能是没有参数的,故Token t2;是不对的;

文法实现

根据我们计算时运用的规则,设计出如下文法:

Expression:
		Term
		Expression + Term
		Expression - Term

Term;
		Primary
		Term * Primary
		Term / Primary
		Term % Primary
Primary:
		Number
		( Experssion )
		- Primary
		+ Primary
		
Number:
		floating-point-literal

以上文法显示出下列规则:

1. 一个Expression必须是一个Term或者以Term结尾;

2. 一个Term必须是一个Primary或者以Primary结尾;

3. 一个Primary必须以( 或者Number开头;

 举例:45 + 11.5 * 7

45为一个Number,进而为一个Primary、Term、Expression,其后跟一个+,因此需要找到一个Term,以实现Expression + Term;

11.5为一个Number,进而为一个Primary、Term,其后跟一个*,因此需要找到一个Primary,以实现Term * Primary;

7为一个Number,进而为一个Primary。

故由文法可判断出45 + 11.5 * 7为一个表达式,且根据判断的顺序,可以实现正确的运算顺序(我们在读取完45 + 后需要先处理Term:11.5 * 7,即先计算了11.5 * 7)。

下面将以上文法转换为代码:

double primary(){
	Token t = get_token();
	switch(t.kind){
		case '(':
			{
				double d = expression();
				t = get_token();
				if(t.kind != ')'){
				perror("')' expected");
				}
				return d;
			}
		case '8':
			return t.value;
		default:
			perror("primary expected");
	}
}

double term(){
	double left = primary();
	Token t = get_token();
	
	while(true){
		switch(t.kind){
			
			case '*':
				left *= primary();
				t = get_token();
				break;
			case '/':
				{
					double d = primary();
					if(d == 0) {
					perror("divide by zero");
					}
					left /= d;
					t = get_token();
					break;
				}
			default:
				return left;
		}
	}
}

double expression(){
	double left = term();
	Token t = get_token();
	
	while(true){
		switch(t.kind){
			
			case '+':
				left += term();
				t = get_token();
				break;
			case '-':
				left -= term();
				t = get_token();
				break;
			default:
				return left;
		}
	}
}

int main()
try{
	while(cin){
		cout << "=" << expression() << endl;
	}
	keep_window_open();
}
/*异常处理*/ 
catch(exception& e){
	cerr << e.what() << endl;
	keep_window_open();
	return 1;
}
catch(...){
	cerr << "exception" << endl;
	keep_window_open();
	return 2;
}

get_token()是从cin流读入一个单词,但这里有两个问题:

1. 暂时没有用的单词被读入后便丢失了,没有被很好的保存起来,以便未来使用;

2. 程序必须在读入下一个单词之后才能输

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
为编写实际的应用程序做好准备:无论你是为了进行软件开发还是进行其他领域的工作。《C++程序设计原理实践(英文版)》假定你的最终目标是学会编写实际有用的程序。以基本概念和基本技术为重点:与传统的C++教材相比,《C++程序设计原理实践(英文版)》对基本概念和基本技术的介绍更为深入。这会为你编写有用、正确.易维护和有效的代码打下坚实的基础。, 用现代C++语言编程:, 《C++程序设计原理实践(英文版)》一方面介绍了通用的程序设计方法(包括面向对象程序设计和泛型程序设计)。另一方面还对软件开发实践中使用最广泛的程序设计语言——C++进行了很好的介绍。《C++程序设计原理实践(英文版)》从开篇就开始介绍现代C++程序设计技术,并介绍了大量关于如何使用C++标准库来简化程序设计的内容。, 适用于初学者以及任何希望学习新知识的人:, 《C++程序设计原理实践(英文版)》主要是为那些从未编写过程序的人编写的。而且已经由超过1000名大学一年级新生试用过。不过,对于专业人员和高年级学生来说,通过观察公认的程序设计大师如何处理编程中的各种问题。同样也会获得新的领悟和指引。, 提供广阔的视野:, 《C++程序设计原理实践(英文版)》第一部分非常广泛地介绍了基本程序设计技术,包括基本概念、设计和编程技术、语言特性以及标准库。这些内容教你如何编写具有输入、输出、计算以及简单图形显示等功能的程序。《C++程序设计原理实践(英文版)》第二部分则介绍了一些更专门性的内容(如文本处理和测试),并提供了大量的参考资料。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值