【C++】学习笔记三——算术运算符

程序源代码地址: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)


程序3.14
#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

自动推断类型一般用在复杂的情况。



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值