程序源代码地址:https://github.com/buaadf/learncpp
Git:git clone git@github.com:buaadf/learncpp.git
C++提供了五种基本的算术运算:加减乘除和取模(+ - * / %)
程序3.10
#include<iostream>
int main()
{
using namespace std;
float hats, heads;
cout.setf(ios_base::fixed, ios_base::floatfield);
cout << "Enter a number: ";
cin >> hats;
cout << "Enter another number: ";
cin >> heads;
cout << "hats = " << hats << "; heads = " << heads << endl;
cout << "hats + heads = " << hats + heads << endl;
cout << "hats - heads = " << hats - heads << endl;
cout << "hats * heads = " << hats * heads << endl;
cout << "hats / heads = " << hats / heads << endl;
cin.get();
cin.get();
return 0;
}
1 运算符优先级和结合性
优先级:先乘除,后加减。
* / %优先级相同,+ -优先级相同,在优先级相同是,看操作数的
结合性
是从左到右还是从右到左。
2 除法
除法运算符(/)的行为取决于操作数的类型,如果两个操作数都是整数,将执行整数除法(舍弃小数);如果有一个(或两个)操作数是浮点数,则结果为浮点数。
程序3.11
#include<iostream>
int main()
{
using namespace std;
cout.setf(ios_base::fixed, ios_base::floatfield);
cout << "Integer division: 9/5 = " << 9 / 5 << endl;
cout << "Floating-point division: 9.0/5.0 = " << 9.0 / 5.0 << endl;
cout << "Mixed division: 9.0/5 = " << 9.0 / 5 << endl;
cout << "double constants: 1e7/9.0 = " << 1e7 / 9.0 << endl;
cout << "float constants: 1e7f/9.0f = " << 1e7f / 9.0f << endl;
cin.get();
return 0;
}
运行结果:
3 取模运算符%
取模即求整数除法的余数。
程序3.12
#include<iostream>
int main()
{
using namespace std;
const int Lbs_per_stn = 14;
int lbs;
cout << "Enter your weight in pounds: ";
cin >> lbs;
int stone = lbs / Lbs_per_stn;
int pounds = lbs % Lbs_per_stn;
cout << lbs << " pounds are " << stone << " stone, " << pounds << " pound(s).\n";
cin.get();
cin.get();
return 0;
}
先用整数除法计算stone,再求余数得pounds。1 stone=14 pounds
4 类型转换
- 将一种算术类型的值赋给另一种算术类型的变量时,C++将对值进行转换;
- 表达式中包含不同的类型时,C++将对值进行转换;
- 将参数传递给函数时,C++将对值进行转换。
4.1初始化和赋值进行的转换
C++允许将一种类型的值赋给另一种类型的变量,值将转换为接收变量的类型。
假设so_long的类型为long,thirty的类型为short,而程序中包含这样的语句:
so_long=thirty;
程序将thirty的值扩展为long,并存储在so_long中,而thirty内容不变。
将一个值赋给范围更大得类型不会有什么问题。但是若是赋给范围较小的类型则会降低精度。
程序3.13演示了一些初始化进行的转换:
#include<iostream>
int main()
{
using namespace std;
cout.setf(ios_base::fixed, ios_base::floatfield);
float tree = 3;
int guess(3.9832);
int debt = 7.2e12;
cout << "tree = " << tree << endl;
cout << "guess = " << guess << endl;
cout << "debt = " << debt << endl;
cin.get();
return 0;
}
编译器还会提醒:“初始化”: 从“double”转换到“int”,可能丢失数据
4.2 以{}方式初始化时进行的转换(C++11)
这种初始化的方式被称为列表初始化(list-initialization)。
列表初始化不允许缩窄(narrowing),即变量的类型可能无法表示赋给它的值,eg.不允许将浮点型转换为整型。
4.3表达式中的转换
当同一个表达式中包含两种不同的算术类型时,C++将执行两种自动转换:一些类型在出现时便会自动转换;有些类型在与其他类型同时出现在表达式中时将被转换。
自动转换:
在计算表达式时,C++将bool、char、unsigned char、signed char和short值转换为int。具体地说,true被转换为1,false被转换为0。这些转换被称为整型提升。例如:
short chickens = 20;
short ducks = 35;
short fowl = chickens + ducks;
执行第三条语句时,C++将chickens和ducks的值转换为int相加,再将结果转换为short。
其他整型提升:如果short比int段,则unsigned short将被转换为int;如果两种类型的长度相同,则unsigned short将被转换为unsigned int。
wchar_t被提升为下列类型中第一个宽度足够存储wchar_t取值范围的类型:int、unsigned int、long、unsigned long。
不同类型进行算术运算时的转换:
(1)如果有一个操作数的类型时long double,则将另一个操作数转换为long double;
(2)否则,如果有一个操作数的类型是double,则将另一个操作数转换为double;
(3)否则,如果有一个操作数的类型是float,则将另一个操作数转换为float;
(4)否则,说明操作数都是整数,因此执行整型提升;
(5)在这种情况下,如果两个操作数都是有符号或无符号的,且其中一个操作数的级别比另一个低,则转换为级别高的类型;
(6)如果一个操作数为有符号的,另一个为无符号的,其无符号的操作数级别比有符号操作数的高,则将有符号操作数转换为无符号操作数所属的类型;
(7)否则,如果有符号类型可表述无符号类型的所有可能取值,则将无符号操作数转换为有符号操作数所属的类型;
(8)否则,将两个操作数都转换为有符号类型的无符号版本。
传统C语言总是将float提升为double,即使两个操作数都是float。
4.4 传递参数时的转换
传递参数时的类型转换通常由C++函数原型控制。然而,也可以取消原型对参数传递的控制,尽管这样做并不明智。在这种情况下,C++将对char和short类型进行整型提升。
另外,为保持与传统C语言中大量代码的兼容性,在将参数传递给取消原型对参数传递控制的函数时,C++将float参数提升为double。
4.5 强制类型转换
C++还允许通过强制类型转换机制显式的进行类型转换。强制类型转换的格式有两种,例如,将变量thorn中的int值转换为long类型,可用:
(long) thorn
long (thorn)
强制类型转换不会修改thorn本身,而是创建一个新的、指定类型的值,可以在表达式中使用这个值。
强制转换的通用格式:
(type) value //来自C语言
type (value) //C++格式
static_cast<>可用于将值从一种数值类型转换为另一种数值类型:
static_cast<type> (value)
#include<iostream>
int main()
{
using namespace std;
int auks, bats, coots;
auks = 19.99 + 11.99;
bats = (int)19.99 + (int)11.99;
coots = int(19.99) + int(11.99);
cout << "auks = " << auks << ", bats = " << bats;
cout << ", coots = " << coots << endl;
char ch = 'Z';
cout << "The code for " << ch << " is ";
cout << int(ch) << endl;
cout << "Yes, the code is ";
cout << static_cast<int>(ch) << endl;
cin.get();
return 0;
}
运行结果:
19.99+11.99=31.98,将其赋给int类型时被截断为31。在进行加法前强制类型转换,则为19+11=30。
5 C++11中的auto声明
在初始化声明时,如果使用关键字auto,而不指定变量的类型,编译器将把变量的类型设置成与初始值相同:
auto n = 100; //n类型为int
auto x = 1.5; //x类型为 double
auto y = 1.3e1L; //y类型为long double
自动推断类型一般用在复杂的情况。