
3.3 常用运算符
在数据处理中,除最基础的赋值运算符外还有很多常用的运算符,包括算术运算符、自增自减运算符、位运算符等,下面将详细进行讲解。
3.3.1 算术运算符
算术运算符包括四则运算加、减、乘、除运算符(+、-、*、/)和取模运算符(%)。加、减、乘、除运算符与数学中的四则运算符相同,在使用除法运算符时,除数(第2个操作数)不能为0。取模运算符的两个操作数必须为整数类型。
算术运算符是双目运算符,也就是需要拥有两个操作数。其操作数一般是整数和浮点数。C++语言中支持的算术运算符如表3.1所示。
表3.1 算术运算符

提示:在算术运算符中也会遵循隐式类型转换规则,如果两个操作数都是整数,则运算的结果也是整数;如果两个操作数类型不同,则自动转换为尺寸较大的数据类型进行计算。
【示例3-6】使用算术运算符运算数据。

程序运行结果如下。

在C++中,算术运算符也有优先级和结合性规则。算术运算符的结合性都是从左到右的;算术运算符的优先级如图3.8所示。

图3.8 算术运算符的优先级
【示例3-7】下面使用算术运算符运算数据。

程序运行结果如下。

在此代码中使用了多个算术运算符,首先会进行除法运算,其次进行取模运算,然后进行加法运算、减法运算,最后再进行加法运算。
3.3.2 正负运算符
生活所接触到数据会有正负之分。同样,C语言使用正负运算符用于数字的正负运算。正负运算符包含两个符号“+”与“-”。
1.正运算符
正运算符(+)属于单目运算符,拥有一个操作数。该运算符一般用于格式上的对齐,并不能让负数变为正数。其语法形式如下。

【示例3-8】下面验证使用正运算符无法改变数的值。

程序运行结果如下。

可以看出代码中的正运算符并没有改变变量a的值。
2.负运算符
负运算符(-)属于单目运算符,拥有一个操作数,可以让数字进行负运算。其语法形式如下。

【示例3-9】下面演示负运算符改变值的正负。

程序运行结果如下。

从代码中可以看出,负运算符将变量a的值进行了正负改变。
3.3.3 复合赋值运算符

图3.9 变量名相同
在进行算术运算时,如果赋值运算符左右两侧的变量名相同,如图3.9所示,就可以使用复合赋值运算符来简化代码。
在C++语言中,为了提高运算效率和简化书写,提供了复合赋值运算符,又称扩展赋值运算符。该类型运算符如表3.2所示。
表3.2 复合赋值运算符

【示例3-10】下面使用加法赋值运算符求和。

程序运行结果如下。

从运行结果中可以看出,a=a+10与a=+10的效果是相同的。
3.3.4 自增自减运算符
在生活中我们常常会做一些简单的计数运算。例如,在App中签到赢取积分,每次签到积分都会增加1。对于这种累加或累减运算使用加法运算符编写程序是没有必要的,因此在C++语言中提供了专门的增量运算符与减量运算符,也就是自增运算符和自减运算符。
1.自增运算符
自增运算符(++)属于单目运算符,拥有一个操作数,操作数必须是变量,适用于整数和小数类型。该运算符可以让变量进行自加运算。根据运算符使用的位置,该运算符有两种语法形式。
(1)前缀自增运算符会让操作数自增1后,再参与其他运算,其语法形式如下。

【示例3-11】下面演示前缀自增运算符的使用。

程序运行结果如下。

在代码std::cout 〈〈 "i的值为" 〈〈 ++i〈〈 std::endl;中,首先i变量会先进行自增,然后才会参与输出,所以输出结果为7,如图3.10所示。

图3.10 分步展示(1)
代码std::cout 〈〈 "i的值为" 〈〈 i 〈〈 std::endl;再次输出i的值,i仍然为7。
(2)后缀自增运算符会让操作数参与运算后,操作数的值再自增1,其语法形式如下。

【示例3-12】下面演示后缀自增运算符的使用。


程序运行结果如下。

在代码std::cout 〈〈 "i的值为" 〈〈 i++ 〈〈 std::endl;中,首先会输出变量i的值,然后变量i进行自增运算,如图3.11所示。

图3.11 分步展示(2)
所以,std::cout 〈〈 "i的值为" 〈〈 i++ 〈〈 std::endl;输出结果为6,std::cout 〈〈 "i的值为" 〈〈i 〈〈 std::endl;输出的结果为7。
2.自减运算符
自减运算符(--)属于单目运算符,拥有一个操作数,操作数必须是变量,适用于整数和小数类型。该运算符可以让变量进行自减运算。根据运算符使用的位置,该运算符有两种语法形式。
(1)前缀自减运算符会让操作数自减1后,再参与其他运算,其语法形式如下。

【示例3-13】下面演示前缀自减运算符的使用。

程序运行结果如下。

在代码中首先变量i会先进行自减,然后才会参与输出,所以两次输出结果都为5。
(2)后缀自减运算符会让操作数参与其他运算后,操作数的值再自减1,其语法形式如下。

【示例3-14】下面演示后缀自减运算符的使用。


程序运行结果如下。

在代码中首先变量i会被输出,然后才会进行自减运算,所以第一次输出为6,第二次输出为5。
3.自增自减运算符使用建议
由于自增自减运算符会涉及多个加号或者减号的使用,所以在一个表达式中要尽量避免多次出现同一类运算。
【示例3-15】下面演示多个自增运算符的使用。

程序运行结果如下。

代码i=i+++i++;中就多次使用了自增运算符,并与加法运算符混合使用。这种写法导致代码可读性极低,而且在不同编译器中运行结果会出现不同。
3.3.5 位运算符
计算机的运算基础是二进制数的运算。在内存中,数据都以二进制形式进行存储。C++语言也提供二进制数值相关的运算符,它们统称为位运算符。位是其中的最小单位,1 字节(byte)由8位(bit)组成。每1位即1bit,8bit=1byte,即1字节,在C++提供了多种位运算符,如表3.3所示。
表3.3 位运算符

位运算符优先级如图3.12所示。在位运算中除按位取反运算符~为右结合外,其他几个位运算符都为左结合。

图3.12 位运算符优先级
1.位逻辑运算符
位的逻辑运算简单来说就是将指定的两个位中的二进制数据进行比较,如果相同,运算结果为1;如果不同,运算结果就为0。二进制数运算涉及的位逻辑运算符包括按位取反运算符、按位与运算符、按位或运算符、按位异或运算符四种,如表3.4所示。
表3.4 位逻辑运算符

1)按位取反运算符
按位取反运算符(~)属于单目运算符,拥有一个操作数,其语法形式如下。

按位取反运算符可以将数值转换为二进制数后按位取反,即0变为1,1变为0。
【示例3-16】下面将1进行取反运算并输出。

程序运行结果如下。

代码中十进制数1的二进制数为00000001,取反运算后为二进制数11111110,即十进制数-2,取反过程如图3.13所示。

图3.13 1取反运算
2)按位与运算符
按位与运算符(&)属于双目运算符,拥有两个操作数,其语法形式如下。

按位与运算符可以将数值转换为二进制数后按位进行与运算。其运算规则是按位比较,都为1时为1,都为0时为0,一个为1一个为0时则为0,如图3.14所示。

图3.14 按位与运算
【示例3-17】下面演示按位与运算,并输出结果。

程序运行结果如下。

代码中十进制数1的二进制数为01,十进制数2的二进制数为10,按位进行与运算,二进制结果为00即十进制数0,如图3.15所示。

图3.15 1&2运算过程
3)按位或运算符
按位或运算符(|)属于双目运算符,拥有两个操作数,其语法形式如下。

按位或运算符可以将数值转换为二进制数后按位进行或运算。其运算规则是按位比较,都为0时为0,都为1时为1,一个为1一个为0时则为1,如图3.16所示。

图3.16 按位或运算
【示例3-18】下面演示按位或运算,并输出运算结果。

程序运行结果如下。

代码中十进制数1的二进制数为01,十进制数2的二进制数为10,按位进行或运算,二进制结果为11即十进制数3,如图3.17所示。

图3.17 1|2运算过程
4)按位异或运算符
按位异或运算符(^)属于双目运算符,拥有两个操作数,其语法形式如下。

按位异或运算符可以将数值转换为二进制数后按位进行异或运算。其运算规则是按位比较,两个值相同时,运算结果为0;两个值不同时,运算结果为1,如图3.18所示。

图3.18 按位异或运算
【示例3-19】下面演示按位异或运算,并输出运算结果。

程序运行结果如下。

代码中十进制数2的二进制数为10,十进制数3的二进制数为11,按位进行异或运算,二进制结果为01即十进制数1,如图3.19所示。

图3.19 2^3运算过程
2.移位运算符
移位运算就是将二进制数据向右或向左移动,如果有空位用0补齐的运算,这样会让数值产生变化。C++语言中的移位运算符包括左移运算符与右移运算符两种,如表3.5所示。
表3.5 移位运算符

1)左移运算符
左移运算符(〈〈)属于双目运算符,拥有两个操作数。操作数1表示要左移的数,操作数2表示要左移的位数。这里的位是指二进制的数值位,1位即1bit,8位为1字节,其语法形式如下。

左移运算符可以将数值转换为二进制数后按位进行左移运算。其运算规则是将二进制数向左移动,右侧移动空下的位置用0补全。例如,表达式11100100〈〈4表示将11100100左移4位,结果为01000000。
【示例3-20】下面演示左移运算,并输出运算结果。

程序运行结果如下。

代码中十进制整数1的二进制数为00000001,左移4位后为00010000,转换为十进制整数为24也就是16,如图3.20所示。

图3.20 1〈〈4运算过程
2)右移运算符
右移运算符(〉〉)属于双目运算符,拥有两个操作数,操作数1表示要右移的值,操作数2表示要右移的位数。这里的位是指二进制的数值位,其语法形式如下。

右移运算符可以将数值转换为二进制数后按位进行右移运算。其运算规则是将二进制数向右移动,左侧移动空下的位置用0补全。例如,表达式11100100〉〉4表示将11100100右移4位,结果为00001110。
【示例3-21】下面演示右移运算,并输出运算结果。


程序运行结果如下。

代码中十进制整数4的二进制数为00000100,右移4位后为00000000,转换为十进制整数为0,如图3.21所示。

图3.21 4〉〉4运算过程
3.3.6 关系运算符
在生活中,我们常常会对两个物体的大小、质量等属性进行比较。在C++语言中,也需要对数据的大小进行比较,如按照年龄为公司员工进行排序。C++语言提供了六种关系运算符,如表3.6所示。
表3.6 关系运算符

关系运算符拥有两个操作数,如下所示。

其运算规则是比较两个操作数的关系是否和关系运算符的含义相同,如果相同,运算结果为1;如果不同,运算结果为0。例如,在表达式3〉2中,因为3确实大于2,与运算符大于号(〉)的含义相同,所以该表达式的运算结果为1。
例如,在表达式3〉5中,3并不大于5,与大于号的含义不同,所以表达式3〉5的运算结果为0。表达式5〉3中,5确实大于3,与大于号的含义相同,所以表达式5〉3的运算结果为1。
【示例3-22】输出关系运算符的运算结果。

程序运行结果如下。

从运行结果中可以看出,每个关系运算符的结果除了1就是0,具体的值由两个操作数的关系是否与当前关系运算符一致决定。
3.3.7 逻辑运算符
C++语言包括逻辑与、逻辑或和逻辑非三种逻辑运算符。逻辑运算符可以对指定的条件进行对错判断然后运算,接下来将进行详细讲解。
1.逻辑与运算
逻辑与运算符(&&)属于双目运算符,拥有两个操作数,其语法形式如下。

其中操作数1与操作数2都属于条件表达式,当两个操作数都为真时,运算结果为1,表示真;否则,运算结果为0,表示假。
2.逻辑或运算
逻辑或运算符(||)属于双目运算符,拥有两个操作数,其语法形式如下。

其中操作数1与操作数2都属于条件表达式,当两个操作数中至少有一个为真时,运算结果为1,表示真;如果两个操作数都为假,则运算结果为0,表示假。
3.逻辑非运算
逻辑非运算符(!)属于单目运算符,拥有一个操作数,其语法形式如下。

操作数属于条件表达式,当操作数为真时,运算结果为0,表示假;当操作数为假时,运算结果为1,表示真。
逻辑运算符的判断条件与运算结果如表3.7所示。
表3.7 逻辑运算符的判断条件与运算结果

逻辑运算优先级如图3.22所示。逻辑运算符!为右结合,运算符&&与运算符||为左结合。

图3.22 逻辑运算优先级
【示例3-23】下面演示逻辑运算符的使用。

程序运行结果如下。

代码运行过程如下。
❑ 在表达式1〉2 && 3〉2 中,1〉2的值为0,3〉2的值为1,因为有一个值为0,所以0&&1的值为0。
❑ 在表达式1〉2 ||3〉2 中,1〉2的值为0,3〉2的值为1,因为有一个1,所以0||1的值为1。
❑ 在表达式a = 1 〉 2与 a = !a中,1〉2的值为0,零取反就是1,所以!0的值为1。
3.3.8 逗号运算符
逗号运算符可以使多个表达式写在一行上,从而大大地简化了程序,语法形式如下。

在声明变量的内容中我们就使用过逗号运算符,例如,可以将代码

写为

在后面将要讲解的条件语句中也会使用大量的逗号运算符。
3.3.9 条件运算符
在生活中我们常常会遇到一些二选一的情况。例如,完成暑假作业的同学可以正常放学,没有完成暑假作业的同学需要叫家长来接。这里面“是否完成暑假作业”就是一个条件,当达到条件后能正常放学,如果没有达到条件则需要叫家长来接。
C++中的条件运算符(?: )就可以用于实现根据条件选择运算结果的效果。条件运算符(?: )属于三目运算符,有三个操作数。操作数1为条件,如果条件为真,则运算结果值为操作数2;如果条件为假,则运算结果值为操作数3。其语法形式如图3.23所示。

图3.23 条件运算符语法形式
【示例3-24】下面使用条件运算符进行运算。

程序运行结果如下。

从代码中可以看出,10〉20的运算结果为假,也就是0,所以表达式10 〉 20 ? 10 : 20的运算结果为20。