你好,C++(14)用表达式表达我们的设计意图——4.1 用操作符对数据进行运算

本文主要是介绍你好,C++(14)用表达式表达我们的设计意图——4.1 用操作符对数据进行运算,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

第4章 将语句编织成程序

学过C++中的各种数据类型, 就知道如何使用各种数据类型定义变量来描述现实世界中的各种事物了。现在,我们可以将一个工资统计程序大致写成下面这个样子:


 

// 工资统计程序
int main()
{// 表示员工个数的常量NUMconst int NUM = 100000;// 保存所有工资的数组int arrSalary[NUM];// 保存平均工资的变量float fSalaryAver = 0.0;   // 对工资进行处理…return 0;
}

但是,我们现在只是知道如何用数据类型定义变量来表示现实世界中的数据,而对于如何处理这些数据以解决问题还一无所知。我们不知道如何方便地输入这100000个工资数据,更不知道如何计算这100000个工资数据的平均工资。程序的两个任务——描述数据和处理数据。现在我们已经完成了第一个任务,用各种类型的变量描述现实世界中的数据。那么接下来,我们就看看在C++中如何完成第二个任务——处理数据,从而获得结果数据最终解决问题。

4.1 用运算符对数据进行运算

对数据的处理最常见的就是对数据进行运算,以获得某个运算结果。就像在现实世界中,我们对1和2 进行加法运算,可以得到运算结果3一样,在C++中,我们同样可以用两个int类型的变量a和b来表示1和2,那么,又如何对a和b进行加法运算得到结果数据3呢?

4.1.1 用表达式表达设计意图

在计算数学题的时候,如果想知道两个数的和,总是先用加法运算符号“+”连接两个加数列出加法算式,然后再计算整个算式得到最终的和值。例如:

1 + 2 = 3

在C++中也是如此,如果想对数据进行处理获得运算结果,就要用一个式子将数据的运算处理过程描述出来,因为这个式子表达了我们对这些数据的处理意图,所以这个式子也被称为表达式。而程序在执行计算一个表达式的时候,会按照这个表达式所描述的运算过程对数据进行运算,最终获得整个表达式的运算结果。

在C++中,一个表达式由操作符、操作数和标点符号(必须是英文的)三部分组成,其作用是描述一个对数据的运算过程。表达式的核心是操作符和操作数。操作数就是要参与运算的数据,它可以是变量表示的数据,也可以是直接表示的常数。而连接这些操作数表达运算意图的各种符号就是操作符了,比如表示加法运算意图的“+”,表示乘法运算意图的“*”等。操作数是操作符的处理对象,而操作符则表达了对所连接的操作数的处理方式。比如,一个加法运算表达式“a + 5”中,变量“a”和常数“5”是这个表达式的操作数,而连接这两个操作数的是加法运算操作符“+”,表示将它所连接的两个操作数“a”和“5”进行加和运算得到结果。如果这个表达式是某个更复杂表达式的一部分,那么这个结果将作为这个表达式的值,继续参与运算,直到最终得出整个表达式的值。例如:


 

// 定义需要用到的变量
int a,b,c;
// a、5是操作数,=是操作符,它描述的是一个赋值运算:将常数5赋值给变量a
a = 5;      
// b、a、5是操作数,=、+都是操作符
// 它描述的计算过程是:先计算变量a和常数5的和,然后将其赋值给变量b
b = a + 5;  
// a、b、c是操作数,=、*、-是操作符,()是标点符号
// 它描述的计算过程是:首先计算变量b和变量a的差,然后将其与变量a相乘计算积,
// 最后将积赋值给变量c。运算过程如图4-1所示。
c = a * (b - a);

图4-1 表达式的计算过程

表达式中的操作符决定了整个表达式中操作数的个数。大多数操作符需要两个操作数,比如加法操作符“+”,就需要一个加数和一个被加数。这种需要两个操作数的操作符称为二元操作符,如常见的加、减、乘、除操作符。另外一些操作符需要一个或者三个操作数,相应地被分别称为一元操作符和三元操作符。C++提供了丰富的操作符,用于表达数据之间复杂的运算关系,如有表示加、减、乘、除的算术操作符,也有表示大小关系的关系操作符等。下面就来分别了解一下如何运用这些操作符以实现对数据的处理。

4.1.2 算术操作符

在开发实践中,用得最多的就是用于数学计算的算术操作符了。C++提供的算术操作符有以下几种。

l +(加):计算两个数的和。

l “-”(减):计算两个数的差。

l “*”:(乘):计算两个数的积。

l /(除):计算两个数的商。

l %(取余):计算两个数的余。

以上算术操作符跟数学中相应运算符的用法相同,意义也是一致的。运用这些算术操作符可以很方便地表达对数据的算术运算。例如:

1 + 2;    // 对1和2这两个操作数进行加法运算,表达式的值为3
4 * 5;    // 对4和5这两个操作数进行乘法运算,表达式的值为20
10 % 7;   // 对10除以7取余,表达式的值为3

另外,C++程序中对数值数据的加1或减1操作非常普遍,为了提高编码效率,C++还提供了可以快捷完成此操作的“++(自增)”和“--(自减)”操作符。它们都是一元操作符,可以放在单个操作数的前面或后面(相应地,分别被称为前置操作符或后置操作符),执行对操作数的加1 或减1操作。例如,我们通常用它来实现一些递增和递减的操作:

int nIndex = 0;
// …
// nIndex自身加1,其值递增为1,等同于nIndex = nIndex + 1
++nIndex;

最佳实践:使用前置自增操作符代替后置自增操作符

虽然前置和后置自增操作符的意义是相同的,都是对操作数进行加1操作,但当这两种操作符的结果要继续用来参与运算时,它们的效果却是不一样的。观察下面这段代码:

int a = 1;    // 定义整型变量a,并给a赋初始值为1
cout<<++a;    // 利用前置的自增操作符对a加1,输出为2,这时a的值为2
cout<<a++;    // 利用后置的自增操作符对a加1,输出还是2,但是a的值为3

第二条语句的输出为2,这是因为当使用前置自增操作符时,a首先进行自增运算,其数值变为2,然后再输出a的值,自然就是2了。但是大家一定会对第三句输出也为2感到奇怪,为什么a同样执行了自增操作,输出还是2呢?这是因为使用了后置自增操作符,输出语句首先要输出a的当前值2,然后a再进行自增运算,其值变为3。前置操作符是先计算后输出,后置操作符却是先输出后计算,计算顺序的不同才导致了这么奇怪的结果。

既然它们这么容易让人产生困惑,那么,在实际运用中,到底该如何选择呢?可以记住这样一条编程经验:使用前置自增操作符代替后置自增操作符。这样做可以带来如下好处:

1. 前置操作符的效率优于后置操作符

在C++底层,后置操作符是通过前置操作符实现的,实质上,使用后置操作符最终使用的还是前置操作符,并且增加了额外的转换消耗。所以,使用前置操作符可以一定程度上提高代码的执行效率。

2. 前置操作符不易使人产生困惑,增加代码的可读性

后置操作符有时会让人丈二和尚摸不着头脑。例如:

int a = 1;
int b = a++ + 1; // 变量b的值到底是2还是3呢?

这段代码执行完成后,b的值是2,而不是3。这是因为这里使用的是后置的自增操作符,它会先把a的当前值1用于计算得到结果2,然后再将其赋值给b并自己增加1变为2。结果虽然简单,可是却难以让人“一眼就看出来”,有时甚至会让人错误地认为结果是3。而如果使用前置操作符,写成:

b = ++a + 1; // 先执行a的自增运算变为2,然后执行加1运算,结果为3

则一眼就可以看出b的值是3,整个代码结果一目了然。

前置的自增操作符可以提高代码的执行效率,同时又增加了代码的可读性,那自然是优先选择使用前置自增操作符了,前置的自减操作符也是同样的道理。

4.1.3 赋值操作符

有了算术操作符,就可以得到各个数据的算术运算结果。但是有了运算结果,还需要把结果保存下来以备后用。而赋值操作符就是用来将结果数据保存到变量的。在C++中,最简单的赋值操作符就是“=”。它是一个二元操作符,其右侧通常是某个常数或表达式,而左侧是某个变量。它的作用就是将右侧的值(如果是表达式,则先计算表达式的值)保存到左侧的变量中,以此实现数据的保存。例如:


 

int a, b, c;
// 将1赋值给变量a,a的值变成1,实现数据1的保存
a = 1;             
// 连续赋值,首先执行“c = 1”表达式,将c赋值为1,
// 然后“c = 1”这个表达式的值为1,继续赋值给b,
// b的值也变为1,继续赋值给a,最后a、b、c都被赋值为1
a = b = c = 1;     
// 先计算“b + 1”表达式的值为2,
// 然后继续将其赋值给a,a的值变成2,实现了表达式计算结果的保存
a = b + 1;         

另外,赋值操作符左侧的变量有时也会参与右侧表达式的运算。这时,将先以左侧变量的当前值参与右侧表达式的运算,然后再将运算结果赋值给左侧变量。例如:

// 先用a的当前值2进行“a+10”的计算,得到结果12
// 然后再将结果数据保存到a,a的值变为12
a = a + 10;
// 先用a的当前值12进行右侧表达式的计算,得到结果24
// 然后再将结果数据保存到a,a的值变为24
a = a * (b + 1);

像这种变量既参与计算又保存结果的赋值操作在C++中非常普遍,为了简化代码,C++还将这些表达式中负责计算的操作符跟赋值操作符结合起来,形成了带计算功能的复合赋值操作符。包括:算术操作符与赋值操作符组合,例如+=、-=、*=、/=、%=;位运算操作符与赋值操作符组合,例如<<=、>>=、&=、^=、|=。

这些复合的赋值操作符同样是二元操作符,它们首先将两侧的操作数按照复合操作符中的算术或位运算操作符进行计算,这时参与计算的是变量的当前值,得到计算结果后再赋值给左侧的操作数,从而在计算的同时完成了赋值,实现了计算和赋值的复合。利用复合赋值操作符,上面的代码就可以简化为:

a += 10;            // 等价于表达式 “a = a + 10”,以此实现对a的递增操作
a *= b + 1;         // 等价于表达式 “a = a * (b + 1)”

这篇关于你好,C++(14)用表达式表达我们的设计意图——4.1 用操作符对数据进行运算的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/712401

相关文章

Java注解之超越Javadoc的元数据利器详解

《Java注解之超越Javadoc的元数据利器详解》本文将深入探讨Java注解的定义、类型、内置注解、自定义注解、保留策略、实际应用场景及最佳实践,无论是初学者还是资深开发者,都能通过本文了解如何利用... 目录什么是注解?注解的类型内置注编程解自定义注解注解的保留策略实际用例最佳实践总结在 Java 编程

一文教你Python如何快速精准抓取网页数据

《一文教你Python如何快速精准抓取网页数据》这篇文章主要为大家详细介绍了如何利用Python实现快速精准抓取网页数据,文中的示例代码简洁易懂,具有一定的借鉴价值,有需要的小伙伴可以了解下... 目录1. 准备工作2. 基础爬虫实现3. 高级功能扩展3.1 抓取文章详情3.2 保存数据到文件4. 完整示例

使用Java将各种数据写入Excel表格的操作示例

《使用Java将各种数据写入Excel表格的操作示例》在数据处理与管理领域,Excel凭借其强大的功能和广泛的应用,成为了数据存储与展示的重要工具,在Java开发过程中,常常需要将不同类型的数据,本文... 目录前言安装免费Java库1. 写入文本、或数值到 Excel单元格2. 写入数组到 Excel表格

C#如何调用C++库

《C#如何调用C++库》:本文主要介绍C#如何调用C++库方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录方法一:使用P/Invoke1. 导出C++函数2. 定义P/Invoke签名3. 调用C++函数方法二:使用C++/CLI作为桥接1. 创建C++/CL

python处理带有时区的日期和时间数据

《python处理带有时区的日期和时间数据》这篇文章主要为大家详细介绍了如何在Python中使用pytz库处理时区信息,包括获取当前UTC时间,转换为特定时区等,有需要的小伙伴可以参考一下... 目录时区基本信息python datetime使用timezonepandas处理时区数据知识延展时区基本信息

Python位移操作和位运算的实现示例

《Python位移操作和位运算的实现示例》本文主要介绍了Python位移操作和位运算的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 位移操作1.1 左移操作 (<<)1.2 右移操作 (>>)注意事项:2. 位运算2.1

Qt实现网络数据解析的方法总结

《Qt实现网络数据解析的方法总结》在Qt中解析网络数据通常涉及接收原始字节流,并将其转换为有意义的应用层数据,这篇文章为大家介绍了详细步骤和示例,感兴趣的小伙伴可以了解下... 目录1. 网络数据接收2. 缓冲区管理(处理粘包/拆包)3. 常见数据格式解析3.1 jsON解析3.2 XML解析3.3 自定义

SpringMVC 通过ajax 前后端数据交互的实现方法

《SpringMVC通过ajax前后端数据交互的实现方法》:本文主要介绍SpringMVC通过ajax前后端数据交互的实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价... 在前端的开发过程中,经常在html页面通过AJAX进行前后端数据的交互,SpringMVC的controll

利用python实现对excel文件进行加密

《利用python实现对excel文件进行加密》由于文件内容的私密性,需要对Excel文件进行加密,保护文件以免给第三方看到,本文将以Python语言为例,和大家讲讲如何对Excel文件进行加密,感兴... 目录前言方法一:使用pywin32库(仅限Windows)方法二:使用msoffcrypto-too

Pandas使用AdaBoost进行分类的实现

《Pandas使用AdaBoost进行分类的实现》Pandas和AdaBoost分类算法,可以高效地进行数据预处理和分类任务,本文主要介绍了Pandas使用AdaBoost进行分类的实现,具有一定的参... 目录什么是 AdaBoost?使用 AdaBoost 的步骤安装必要的库步骤一:数据准备步骤二:模型