C++学习日记(9)——C++算术运算符

我相信屏幕前的你们都能熟练的完成加减乘除等运算

计算机当然也可以,甚至速度比我们更快

只不过它的理解方式和我们的可能会稍微有点不一样

下面先介绍五个基本的C++算术运算符

  • +运算符,就是执行加法运算
  • -运算符,执行减法运算
  • *运算符,执行乘法运算(✖乘号计算机不认得)
  • /运算符,用第一个数除于第二个数,如果两个数都是整数
  • 那么结果就是商的整数部分(不留小数),12/7=1
  • %运算符,一般我们是叫取余,当然更标准的说法是取模
  • 例如19%6=1,因为19/3=6,余数为1

%这个运算符是有硬性规定的,两个对象都必须是整型

你如果用在浮点数上面就会导致编译错误


运算符优先级和结合性

优先级遵循代数的优先级

也就是先乘除后加减

优先级表还是挺长的

结合性是啥意思呢

就是遇到像5/3*4的情况

两个优先级一样的时候就参考结合性


除法分支

来看看C++除法是怎么处理不同类型的值

  • 9/5=1
  • 9.0/5.0=1.800000
  • 9.0/5=1.800000
  • 1e7/9.0=1111111.111111
  • 1e7f/9.0f=1111111.125000

怎么样,是不是跟你想象的完全不一样

第一个没什么问题,概念看完应该都能理解

第二第三为什么都保留了6位小数呢?

float最高保证6位有效位,而double保证15位

但是在IDE里面都只能显示6位

如果你想显示后面的位数

需要#include <iomanip>

然后在输出语句之前插入cout << setprecision(20)

来强制输出小数位

最后一个,两个数后面的f又是什么意思呢?

这里要提到一个上节没讲的概念浮点常量

默认情况下,像9.0和1e7都是double类型的

如果你希望常量是float类型,那就在后面加上f或者F

如果想要long double,就加上L,l看起来像1所以我们不使用


类型转换

因为有11种整型和3种浮点类型

计算机需要处理大量不同的情况

为了处理这种潜在的混乱

C++会自动执行很多的类型转换

  • 将一种算术类型的值赋给另一种算术类型的变量时,C++会对值进行转换;
  • 表达式中包含不同的类型的时候,C++会对值进行转换;
  • 将参数传递给函数时,C++会对值进行转换;

初始化和赋值进行的转换

int long a;

int short b;

a=b;

赋值的时候b的值就会从short的16位扩展成long的32位

将一个值赋给范围更大的变量通常问题不大

但是把更大的值赋给范围小的变量就有可能会出事了

  • 大的浮点类型转换为小的浮点类型(有效的位数降低了)
  • 浮点类型转换为整型(小数部分没了)
  • 大的整型转换位小的整型(优先保留右边的字节)

以{}方式初始化时进行的转换(C11)

C11把使用大括号的初始化叫做列表初始化

(前面提到过的,忘了的话可以翻一下函数那里)

这种初始化通常用于更复杂的数据类型提供值列表

它是不允许缩窄的,也就是说更大的值赋给更小范围的变量不被允许

表达式里的转换

通常这部分的转换都是IDE自动完成的

大家只要了解即可

在计算表达式的时候

bool/char/unsigned char/signed char/short

这些值都会被转换成int

true被转换为1,false被转换为0

这些转换叫做整型提升

例如

short a = 10;

short b = 20;

short c = a+b;

在执行最后一条语句的时候,a和b的值都会被转换成整型

然后计算后再把数据转换成short

因为int对计算机来说处理效率最高,通常IDE都会这么干

还有一些其它的整型提升

例如short比int短的话,unsigned short就会转换成int

如果两种类型相同,unsigned short就会转换成unsigned int

不同类型相加时,也会做一些转换

例如int+float,int就会被转化为float

编译器通过校验表来确定表达式中执行的转换

下面是C11版本的校验表

  • 如果有一个操作数的类型是 long double,则将另一个操作数转换为 long double。
  • 否则,如果有一个操作数的类型是 double,则将另一个操作数转换为 double。
  • 否则,如果有一个操作数的类型是 float,则将另一个操作数转换为 float。
  • 否则,说明操作数都是整型,因此执行整型提升。
  • 在这种情况下,如果两个操作数都是有符号或无符号的,且其中一个操作数的级别比另一个低,则转换为级别高的类型。
  • 如果一个操作数为有符号的,另一个操作数为无符号的,且无符号操作数的级别比有符号操作数高,则将有符号操作数转换为无符号操作数所属的类型。
  • 否则,如果有符号类型可表示无符号类型的所有可能取值,则将无符号操作数转换为有符号操作数所属的类型。
  • 否则,将两个操作数都转换为有符号类型的无符号版本。

传递参数时的转换

传递参数的类型转换通常由函数原型控制

那如果我们不用函数原型控制的话

char和short将会使用整型提升

float会提升为double


强制类型转换

前面我们说的都是IDE来完成的,自动的类型转换

接下来这部分是我们主动完成的,手动的类型转换

假设有一个int的变量test,要强制转换为long怎么办

你可以这么写

(long) test C的写法 或者 long (test) C++的写法

test本身是没有被修改的,而是创建了一个新的指定类型的值

可以在表达式中直接使用这个值

C++还引入了四个强制类型转换运算符

使用要求会更加的严格

这里先介绍一个会用得到的

static_cast<>可以把值从一种类型转换为另一种数值类型

static_cast<long>(test)

尖括号里面是转换的类型,圆括号里是变量


C11中的auto声明

auto是一个C语言的关键字

但基本不会使用

C11里面重新定义了auto这个关键字

使用auto能让IDE根据初始值的类型来推断变量的类型

auto n = 100;

auto x = 1.5;

auto y=1.32el2L;

但是使用auto容易被报错

假设你想要xyz都是double类型

auto x = 0.0;  正确

double y = 0;  正确

auto z = 0;       错误

 

发表评论

您的电子邮箱地址不会被公开。