3.4 C++算术运算符
- +运算符对操作数执行加法运算。例如,4+20等于24。
- −运算符从第一个数中减去第二个数。例如,12−3等于9。
- 运算符将操作数相乘。例如,28 4等于112。
- /运算符用第一个数除以第二个数。例如,1000/5等于200。如果两个操作数都是整数,则结果为商的整数部分。例如,17/3等于5,小数部分被丢弃。
- +运算符对操作数执行加法运算。例如,4+20等于24。
- −运算符从第一个数中减去第二个数。例如,12−3等于9。
- 运算符将操作数相乘。例如,28 4等于112。
- /运算符用第一个数除以第二个数。例如,1000/5等于200。如果两个操作数都是整数,则结果为商的整数部分。例如,17/3等于5,小数部分被丢弃。
- %运算符求模。也就是说,它生成第一个数除以第二个数后的余数。例如,19%6为1,因为19是6的3倍余1。两个操作数必须都是整型,将该运算符用于浮点数将导致编译错误。如果其中一个是负数,则结果的符号满足如下规则:(a/b)*b + a%b = a。
%的操作数只能是整数
运算符重载简介
在程序清单3.11中,除法运算符表示了3种不同的运算:int除法、float除法和double除法。C++根据上下文(这里是操作数的类型)来确定运算符的含义。使用相同的符号进行多种操作叫做运算符重载(operator overloading)。C++有一些内置的重载示例。C++还允许扩展运算符重载,以便能够用于用户定义的类,因此在这里看到的是一个重要的OOP属性
重量单位英石转换为磅程序:
#include<climits>
using namespace std;
int main()
{
const int Lbs_per_stn = 14;
int labs;
cin >> labs;
int stone = labs / Lbs_per_stn;
int pounds = labs % Lbs_per_stn;
cout << labs << "pounds are " << stone << " stone, " << pounds << "pounds" << endl;
return 0;
}
3.4.4 类型转换
1.初始化和赋值进行的转换
C++允许将一种类型的值赋给另一种类型的变量。这样做时,值将被转换为接收变量的
类型。
将一个值赋给值取值范围更大的类型通常不会导致什么问题。例如,将short值赋给long变量并不会改变这个值,只是占用的字节更多而已。然而,将一个很大的long值(如2111222333)赋给float变量将降低精度。因为float只有6位有效数字,因此这个值将被四舍五入为2.11122E9。
#include<climits>
using namespace std;
int main()
{
cout.setf(ios_base::fixed,ios_base::floatfield);
float tree = 3;
int guess(3.9832);
int debt = 7.2E12;
cout << "guess = " << guess << endl;
cout << "debt = " << debt << endl;
return 0;
}
在这个程序中,将浮点值3.0赋给了tree。将3.9832赋给int变量guess导致这个值被截取为3。将浮点型转换为整型时,C++采取截取(丢弃小数部分)而不是四舍五入(查找最接近的整数)。最后,int变量debt无法存储3.0E12,这导致C++没有对结果进行定义的情况发生。在这种系统中,debt的结果为1634811904,或大约1.6E09。
2.以{ }方式初始化时进行的转换(C++11)
C++11将使用大括号的初始化称为列表初始化(list-initialization),因为这种初始化常用于给复杂的数据类型提供值列表。与程序清单13.3所示的初始化方式相比,它对类型转换的要求更严格。具体地说,列表初始化不允许缩窄(narrowing),即变量的类型可能无法表示赋给它的值。例如,不允许将浮点型转换为整型。在不同的整型之间转换或将整型转换为浮点型可能被允许,条件是编译器知道目标变量能够正确地存储赋给它的值。例如,可将long变量初始化为int值,因为long总是至少与int一样长;相反方向的转换也可能被允许,只要int变量能够存储赋给它的long常量:
3.表达式中的转换
先来看看自动转换。在计算表达式时,C++将bool、char、unsigned char、signed char和short值转换为int。
将不同类型进行算术运算时,也会进行一些转换,例如将int和float相加时。当运算涉及两种类型时,较小的类型将被转换为较大的类型。
(1)如果有一个操作数的类型是long double,则将另一个操作数转换为long double。
(2)否则,如果有一个操作数的类型是double,则将另一个操作数转换为double。
(3)否则,如果有一个操作数的类型是float,则将另一个操作数转换为float。
(4)否则,说明操作数都是整型,因此执行整型提升。
(5)在这种情况下,如果两个操作数都是有符号或无符号的,且其中一个操作数的级别比另一个低,则转换为级别高的类型。
(6)如果一个操作数为有符号的,另一个操作数为无符号的,且无符号操作数的级别比有符号操作数高,则将有符号操作数转换为无符号操作数所属的类型。
(7)否则,如果有符号类型可表示无符号类型的所有可能取值,则将无符号操作数转换为有符号操作数所属的类型。
(8)否则,将两个操作数都转换为有符号类型的无符号版本。
4.传递参数时的转换
5.强制类型转换
为将存储在变量thorn中的int值转换为long类型,可以使用下述表达式中的一种:
(long) thorn
long (thorn)
第一种格式来自C语言,第二种格式是纯粹的C++。新格式的想法是,要让强制类型转换就像是函数调用。这样对内置类型的强制类型转换就像是为用户定义的类设计的类型转换。
static_cast<>。
#include<climits>
using namespace std;
int main()
{
int auks, bats, coots;
auks = 19.99 + 11.99;
coots = int(19.99) + int(11.99);
cout << "auks = " << auks << ",bats=" << bats;
cout << ",coots = " << coots << endl;
cout << "the code for " << ch << " is ";
cout << int(ch) << endl;
cout << "yes,the code is " << static_cast<int>(ch) << endl;
system("pause");
return 0;
}
3.4.5 C++11中的auto声明
C++11新增了一个工具,让编译器能够根据初始值的类型推断变量的类型。