21天学通C++(第5版)
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

3.2 表达式

表达式是由运算符和操作数组成的式子,运算符可以是3.1.9节介绍过的各种运算符。操作数包含了常量、变量、函数和其他一些命名的标识符,最常见的表达式是常量和变量。此外,由于C++中运算符很丰富,因此表达式的种类也很多。常见的表达式有如下6种:

●算术表达式。例如,a+5.2/3.0-9%5

●关系表达式。例如,'m'>='x'

●逻辑表达式。例如,!a&&8||7

●条件表达式。例如,a>4?++a:--a

●赋值表达式。例如,a=7

●逗号表达式。例如,a+5,a=7,a+=4

上述表达式的示例中,a表示一个整型变量。除此之外,在具体的应用程序中使用表达式还需要注意如下事项:

●编译系统将按尽量取大的原则来分割多个运算符。例如,表达式a+++b;将被认为是(a++)+b(注意:在Visual C++中这种写法是错误的,编译将不能通过)。

●C++中可使用一对括号()来确定运算符组合。

在C++中,使用运算符之前,有时需要确定其功能,因为有些运算符相同但功能不同。例如,运算符:*、&、-,其有时是单目运算符,而有时是双目运算符。此外,表达式的运算顺序也是非常重要的,一般情况下,计算顺序由左至右,但其需要考虑到运算符的优先级和结合性。

表达式的类型由运算符的种类和操作符的类型决定。不同类型的表达式的求值方法和确定类型的方法也是不同的,下面的章节将逐一介绍。

3.2.1 算术表达式

算术表达式是由算术运算符和位操作运算符组成的表达式,其表达式的值是一个数值。表达式的类型具体由运算符和操作数决定。

【范例3-4】算术表达式的应用。该范例使用到了较为复杂的算术表达式,其功能是计算该算术表达式的值,输出其结果和变量的变化情况,实现代码如代码清单3-4所示。

代码清单3-4

【运行结果】编译执行上述代码,其执行结果如图3-4所示。

图3-4 算术表达式

【范例解析】范例3-4代码中,根据算术运算符的优先级,计算算术表达式7*2+-3%5-4/3的值,并将其结果赋值给a。此外,根据递增或递减运算符计算表达式(m++)-(--n)的值并将其结果赋值给b,最后将这些变量和结果输出。

警告

在上述代码中需要注意的是,语句b=(m++)-(--n);在Visual C++中执行时必须使用括号将其运算顺序明确,否则将出现错误。

例如,如果写成如下格式:

那么在Visual C++中编译时系统将会出现如图3-5所示的错误信息。

图3-5 错误信息

3.2.2 关系表达式

由关系运算符组成的表达式为关系表达式。关系表达式的运算结果为逻辑型,常用在条件语句和循环语句中。同样,此处也通过一个简单程序段查看关系表达式的使用。

【范例3-5】关系表达式的应用。如代码清单3-5给出了多个关系表达式,在程序中计算这些表达式的结果并输出,读者可尝试分析其最终执行结果。

代码清单3-5

【运行结果】读者知道,在关系运算中,关系运算的结果为真时值等于1,结果为假时值等于0。那么上述程序段在Visual C++中执行的结果如图3-6所示。

图3-6 关系表达式

【范例解析】在范例3-5代码中,由于字符之间采用ASCII码进行比较,而字母“m”的ASCII码值要小于“n”的值,表达式x<y成立,因此第一个n的值为true,即为1。字母“m”的ASCII码值比“n”的ASCII值要小1,表达式x==y-1是成立的,因此第二个n的值也为1。第三个表达式('y'!='Y')+(5<3)+(y-x==1)中,字母“y”与“Y”的ASCII值不同,小写字母的ASCII码要大于大写字母,因此('y'!='Y')的值为1,而(5<3)的值为0,同时(y-x==1)的值为1,第三个n的值为1+0+1,即结果为2,因此就得到了如图3-6所示的结果。

注意

在字符的比较中,是比较字符的ASCII码大小。其中,字符往后,ASCII码越大,而小写字母的ASCII码大于大写字母的ASCII码。

3.2.3 逻辑表达式

由逻辑运算符组成的表达式称为逻辑表达式。逻辑表达式的值为逻辑型,其结果也为true和false,但在程序中则表示为1和0。

在由&&和||运算符组成的逻辑表达式中,在C++中规定:只对能够确定整个表达式值所需要的最少数目的子表达式进行计算。也就是说,当计算出一个子表达式之后便可确定整个逻辑表达式的值时,后面的子表达式就不需要再计算了,整个表达式的值就是该子表达式的值,这种表达式也称为短路表达式。

【范例3-6】逻辑表达式的应用。该范例计算一个逻辑表达式的结果,并将其结果输出,实现代码如代码清单3-6所示。

代码清单3-6

【运行结果】上述程序中使用了两个逻辑表达式,分别计算其值并输出,在Visual C++中编译后,其执行结果如图3-7所示。

图3-7 逻辑表达式

【范例解析】在范例3-6程序中,第一个逻辑表达式!a&&a+b&&a++是一个由&&组成的逻辑表达式,从左至右计算三个子表达式,只要有一个为0就不再计算其他子表达式。当计算!a的值为0时,便可确定整个表达式的值为0,因此后面的子表达式就不再计算了。因此,result的值为0。

第二个逻辑表达式!a||a++||b++是一个由||组成的逻辑表达式,从左至右计算三个子表达式,只要有一个结果为真,则不再计算后面的子表达式。第一个子表达式为!a结果为0,再计算a++结果为4,所以就不再计算后面的子表达式。因此,result的值为0。

提示

短路表达式只需要计算许多子表达式中的若干个,这样可以大大减小计算机的运算量。

3.2.4 条件表达式

由三目运算符“?:”组成的表达式为条件表达式。例如,a>b?x=4:x=9;条件表达式的值取决于“?”前面的表达式的值,该表达式的值为非0时,整个表达式的值为“:”符前面的表达式的值,否则为“:”符后面的表达式的值。

【范例3-7】条件表达式的应用。该范例使用到了两个条件表达式,并将其结果赋值给变量,输出该变量的结果,实现代码如代码清单3-7所示。

代码清单3-7

【运行结果】上述程序中使用了两个条件表达式,分别计算其值并输出,在Visual C++中编译后,其执行结果如图3-8所示。

图3-8 条件表达式

【范例解析】在范例3-7程序中,第一个条件表达式a>b?++a:++b中,表达式a>b为假,那么整个表达式的值取++b的值,也即变量c的值为5,而b经过++b的运算其值也为5,因此第一个输出a、b、c分别对应的值为3、5、5。

第二个条件表达式a-b?a-3?b:b-a:a包含潜嵌套的条件表达式,根据条件表达式的结合性,先计算后一个条件表达式的值,表达式a-3的值为0,则取b-a的值2,即子条件表达式的值为2,而表达式a-b的值为非0,那么整个表达式的值取子条件表达式的值2,因此第二个输出a、b、c分别对应的值为3、5、2。

注意

在条件表达式中还可以嵌套条件表达式,此时要先计算最里层的条件表达式的值,将其值替代表达式后依次往外计算,直到完成最外层条件表达式的计算,得到结果为止。

3.2.5 赋值表达式

由赋值运算符组成的表达式为赋值表达式。赋值运算符除了“=”之外还有10个复合运算符,这是赋值和运算相结合的运算符。赋值运算符的结合性是由右至左,因此,在C++程序中允许出现连赋值的情况。例如,下面的赋值是合法的。

此处先计算5/2结果为2,再赋值给d,结果d=5/2表达式的值为2,再将这个值赋给c,依此类推,结果a、b、c、d的值均为2。

在计算复合赋值运算符表达式中,首先计算右值表达式的值后再与左值运算。例如:

此处先计算b+1等于5,再与a相乘赋值给a,结果等于15。

【范例3-8】赋值表达式的应用。该范例包含多个赋值表达式,在Visual C++中运行,读者可查看其执行效果是否与预计的相同,实现代码如代码清单3-8所示。

代码清单3-8

【运行结果】将范例3-8的代码段与前面的两个示例结合起来,并放在Visual C++中执行,其执行结果如图3-9所示。读者可以看到其运行结果与预期的相同。

图3-9 赋值表达式

【范例解析】在范例3-8代码中包含了一个对多个变量同时赋值的赋值表达式a=b=c=d=5/2,其运算顺序为从右到左,最终结果是变量a、b、c和d的值都为5/2整除运算的结果2。使用复合运算符“*=”后,得出m的值并将其输出。

提示

上述代码第7行中输出变量值的语句中,“\t”表示两个输出值之间相隔一个TAB字符的距离,以便区分。

3.2.6 逗号表达式

逗号表达式是用逗号将若干个表达式连起来组成的表达式,其值是组成逗号表达式的若干个子表达式中的最后一个子表达式的值,类型也是最后一个子表达式的类型。

【范例3-9】逗号表达式的应用。该范例应用逗号表达式,将结果赋值给变量后将其输出,实现代码如代码清单3-9所示。

代码清单3-9

【运行结果】在Visual C++中执行上述代码后的输出结果如图3-10所示。

图3-10 逗号表达式

【范例解析】在范例3-9代码中,第一次输出的结果为a、b、c对应的值,根据赋值语句,其值分别为1,2,6。第二次输出是经过了逗号表达式,整个表达式的值为最后一个表达式a-b的值,也即a++后a为2,a+=b后a为4,a-b后a为2,那么整个表达式的值为2,即c的值为2。因此,经过该表达式后,a、b、c对应的值为4,2,2。

提示

逗号表达式在实际程序中应用得不是太多,一般只在特定的场合中才需要使用。