2.3 表达式与类型转换
2.3.1 表达式
表达式是由操作数和运算符按一定的语法形式组成的符号序列。每个表达式经过运算后,都会有一个确定的值,并且这个值一定属于某一特定类型。表达式的求值顺序取决于表达式中各种运算符的优先级与结合性。C++常用运算符的功能、优先级和结合性如表2.4所示。
表2.4 C++中常用运算符的功能、优先级和结合性
1. 算术表达式
算术表达式是指由算术运算符和位操作运算符组成的表达式。接下来演示算术表达式求值,如例2-2所示。
例2-2
运行结果如图2.8所示。
在例2-2中,程序有3个算术运算表达式,在计算时,需要注意以下几点:
- 整数型相除,商值为整型。本例中4/7值为0,14/5值为2。
- 字符常量在算术表达式中会自动转换为int型,即使用它的ASCII码值。本例中第5行字符'a'的取值为97。
图2.8 例2-2运行结果
- 在赋值表达式a=c+++--d中,系统自动将表达式拆解为a=c+++--d。计算时,先计算c++,表达式值为6,c为7,再计算--d,表达式值为3,d为3,再将c++与--d两个表达式值相加赋值给a,因此a的值为9。
2. 关系表达式
关系表达式是由关系运算符组成的表达式。接下来演示关系表达式求值,如例2-3所示。
例2-3
运行结果如图2.9所示。
图2.9 例2-3运行结果
在例2-3中,程序有4个关系表达式,关系运算实际上是比较两个操作数是否符合给定的条件。若符合条件,则关系表达式的值为真,否则为假。在C++编译系统中,通常将真表示为true或1,将假表示为false或0。非0数被认为是真,0被认为是假。如本例中第6行,因为字符'a'的ASCII码值大于字符'A'的ASCII码值,所以表达式'a'<'A'的值为0。
3. 逻辑表达式
逻辑表达式是将多个关系表达式或逻辑量(真或假)组成的一个表达式,它的运算结果也为真或假。逻辑表达式求值有特殊规定:在逻辑表达式中,各操作数从左至右依次计算,只要出现了某个操作数的值可以确定整个逻辑表达式的值时,后面余下的操作数将不会再计算。接下来演示逻辑表达式求值,如例2-4所示。
例2-4
运行结果如图2.10所示。
图2.10 例2-4运行结果
在例2-4中,程序有两个逻辑表达式:第一个逻辑表达式!a&&b++||++c,!a为假,则得出!a&&b++为假,此时不会执行b++,b的值为6,再执行++c,此时c为7,整个逻辑表达式!a&&b++||++c的值为真;第二个逻辑表达式a||--b&&c++,根据优先级,此表达式等价于a||(--b&&c++),因为a的值为真,所以不需要再计算--b&&c++,--b与c++也不会执行,整个逻辑表达式a||--b&&c++的值为真。
4. 条件表达式
条件表达式是指使用三目运算符组成的表达式,因为它具有简单的条件语句的功能。接下来演示条件表达式求值,如例2-5所示。
例2-5
运行结果如图2.11所示。
图2.11 例2-5运行结果
在例2-5中,使用了三目运算符的嵌套,注意该运算符的结合性是从右至左的。程序中条件表达式实现的功能是:如果a大于b,则c为2∗a;如果a小于b,则c为a+b;如果a等于b,则c为0。
5. 逗号表达式
逗号表达式是指由逗号运算符将若干个表达式连成的表达式。逗号运算符是优先级最低的运算符,它可以使多个表达式放在一行上,从而大大简化了程序。接下来演示逗号表达式的使用,如例2-6所示。
例2-6
运行结果如图2.12所示。
图2.12 例2-6运行结果
在例2-6中,(a=2,b=a+3,b+4)为逗号表达式,C++将从左至右逐个计算每个表达式,最终整个表达式的结果就是最后计算的那个表达式的类型和值,因此c的值为9。
2.3.2 自动类型转换
自动类型转换是由编译器编译时自动完成转换的。在C++中,自动类型转换的规则如下:
- 算术运算中的自动转换是以较高类型为准进行转换的。较高类型指存储空间较大者的类型,C++中的基本数据类型级别如图2.13所示。
图2.13 C++中基本数据类型的类型级别
- 赋值运算符的自动转换以赋值号左侧的变量类型为准进行转换。
- 在函数中,实参类型以形参类型为准进行转换,函数返回值类型以函数声明中的返回值类型为准进行转换。
2.3.3 强制类型转换
在任何表达式中,编程者都可以将某个量强制转换成所需要的类型。强制类型转换的语法格式如下:
(类型名)表达式 类型名(表达式)
第一种格式来自C语言,第二种格式是纯粹的C++。C++格式的强制类型转换就是让使用者像函数调用一样,具体示例如下:
cout <<double(6)/4<<endl;
上面语句中,表达式double(6)/4先进行强制类型转换,将6转换成double类型,但除法运算符右边的4为int类型,此时对4进行自动类型转换,将4转换成double类型,最后进行除法运算,结果为1.5,它是double类型的。
关于类型转换还需注意它占用系统时间,并且有时会带来意想不到的错误,因此应谨慎使用。