5种基本C++算术运算符:
- +:加法;
- -:减法;
- *:乘法;
- /:除法;(如果都是整数,小数部分被丢弃)
- %:求模;(必须都是整数,浮点数将编译错误)
3.4.1 运算符优先级和结合性
算术运算符遵循通常的代数优先级:先乘除、后加减。3.4.2 除法分支
除法运算符 / 的行为取决于操作数的类型。如果都是整数,小数部分被丢弃;如果有一个是浮点数,结果是浮点数。示例: ```cppinclude
using namespace std;
int main() { cout.setf(ios_base::fixed, ios_base::floatfield);
cout << "9/5 = " << 9/5 << endl;
cout << "9.0/5.0 = " << 9.0/5.0 << endl;
cout << "9.0/5 = " << 9.0/5 << endl;
cout << "1e7/9.0 = " << 1e7/9.0 << endl;
cout << "1e7f/9.0f = " << 1e7f/9.0f << endl;
return 0;
}
输出:
> 9/5 = 1
> 9.0/5.0 = 1.800000
> 9.0/5 = 1.800000
> 1e7/9.0 = 1111111.111111
> 1e7f/9.0f = 1111111.125000
<a name="uvNRf"></a>
# 3.4.3 求模运算符
返回除法的余数,与除法结合适用于解决要求将一个量分成不同整数单元的问题,如单位换算。
<a name="SFY5R"></a>
# 3.4.4 类型转换
C++自动执行很多类型转换:
1. 初始化和赋值进行的转换
将值赋给取值范围更大的类型不会有什么问题,只是占用更多字节而已;返回来会降低精度。
2. 以 {} 方式初始化时进行的转换(C++11)
C++11使用大括号的初始化称为列表初始化(list-initialization),常用于给复杂的数据类型提供值列表。这种方式不允许缩窄(narrowing),如不能将浮点数转换为整型。
3. 表达式中的转换
这种情况下,C++执行两种自动转换:一些类型出现时就自动转换;有些类型与其他类型同时出现在表达式中时被转换。
在计算表达式时,C++将 bool、char、unsigned char、signed char、short 转换为 int。例如:
```cpp
short num1 = 20;
short num2 = 35;
//先将 num1、num2 转换为 int 类型(整数提升),执行加法运算后再转换成 short 赋值给 num3。
short num3 = num1 + num2;
一般来说,较小的类型将被转换为较大的类型。编译器通过校验表来依次确定转换,以下是C++11的校验表:
- 如果有 long double,另一个操作数转换为 long double;
- 如果有 double,另一个操作数转换为 double;
- 如果有 float,另一个操作数转换为 float;
- 如果都是整型,执行整型提升;
- 如果都是有符号或无符号,且其中一个操作数级别低,则转换为级别高的;
- 如果一个有符号另一个无符号,且无符号的级别高,则转为无符号;
- 如果有符号的可以表示无符号的所有可能取值,则无符号的转为有符号;
否则,将两个都转为无符号的。
传递参数时的转换
这种情况,C++对 char、short 进行整数提升。为保持 C 兼容性,将 float 提升为 double。
- 强制类型转换
强制类型转换不会修改 num 变量本身,而是创建一个新的指定类型的值。两种强制类型转换写法:
(long)num; //C风格
long(num); //C++风格。其想法是让强制类型转换就像函数调用。
3.4.5 C++11中的 auto 声明
示例:
auto n1 = 100; //n1是一个int
auto n2 = 1.5; //n2是一个double
auto n3 = 1.3e12L; //n3是一个long double
auto 的真正用途是处理复杂类型,例如:
//C++98代码
std::vector<double> list;
std::vector<double>::iterator iter = list.begin();
//C++11代码
std::vector<double> list;
auto iter = list.begin();