当前课程知识点:C++语言程序设计基础 > 第2章 C++简单程序设计(一) > 运算与表达式 > 运算优先级、类型转换
运算优先级、类型转换
优先级 | 运算符 | 结合性 |
1 | [ ] ( ) . –> 后置 ++ 后置 –– | 左→右 |
2 | 前置 ++ 前置 –– sizeof & * +(正号) –(负号) ~ ! | 右→左 |
3 | (强制转换类型) | 右→左 |
4 | .* ->* | 左→右 |
5 | * / % | 左→右 |
6 | + – | 左→右 |
7 | << >> | 左→右 |
8 | < > <= >= | 左→右 |
9 | == != | 左→右 |
10 | & | 左→右 |
11 | ^ | 左→右 |
12 | | | 左→右 |
13 | && | 左→右 |
14 | || | 左→右 |
15 | ? : | 右→左 |
16 | = *= /= %= += –= <<= >>=&= ^= |= | 右→左 |
17 | , | 左→右 |
l 一些二元运算符(算术运算符、关系运算符、逻辑运算符、位运算符和赋值运算符)要求两个操作数的类型一致。
l 在算术运算和关系运算中如果参与运算的操作数类型不一致,编译系统会自动对数据进行转换(即隐含转换),基本原则是将低类型数据转换为高类型数据。
条件 | 转换 | |
有一个操作数是long double型。 | 将另一个操作数转换为long double型。 | |
前述条件不满足,并且有一个操作数是double型。 | 将另一个操作数转换为double型。 | |
前述条件不满足,并且有一个操作数是float型。 | 将另一个操作数转换为float型。 | |
前述条件不满足(两个操作数都不是浮点数)。 | 有一个操作数是unsigned long long型。 | 将另一个操作数转换为unsigned long long型。 |
有一个操作数是long long型,另一个操作数是unsigned long型 | 两个操作数都转换为unsigned long long型。 | |
前述条件不满足,并且有一个操作数是unsigned long型。 | 将另一个操作数转换为unsigned long型。 | |
前述条件不满足,并且有一个操作数是long型,另一个操作数是unsigned int型。 | 将两个操作数都转换为unsigned long型。 | |
前述条件不满足,并且有一个操作数是long型。 | 将另一个操作数转换为long型。 | |
前述条件不满足,并且有一个操作数是unsigned int型。 | 将另一个操作数转换为unsigned int型。 | |
前述条件都不满足 | 将两个操作数都转换为int型。 |
l 将一个非布尔类型的算术值赋给布尔类型时,算术值为0则结果为false,否则结果为true。
l 将一个布尔值赋给非布尔类型时,布尔值为false则结果为0,布尔值为true则结果为1
l 将一个浮点数赋给整数类型时,结果值将只保留浮点数中的整数部分,小数部分将丢失。
l 将一个整数值赋给浮点类型时,小数部分记为0。如果整数所占的空间超过了浮点类型的容量,精度可能有损失。
l 显式类型转换的作用是将表达式的结果类型转换为类型说明符所指定的类型。
l 语法形式
n 类型说明符(表达式)
n (类型说明符)表达式
n 类型转换操作符<类型说明符>(表达式)
n 类型转换操作符可以是:
const_cast、dynamic_cast、reinterpret_cast、static_cast
l 例:int(z), (int)z, static_cast<int>(z)
三种完全等价
大家好
欢迎继续学习C++语言程序设计
这一节给大家介绍
运算优先级以及类型转换
到现在为止我们已经学了
很多运算符了 这些运算符呢
如果在一个表达式中
进行混合运算的时候
它们的优先级是什么样的呢
这一级要给大家看一个优先级表
那么还有呢
当我们在同一个表达式中
出现了不同的操作数类型的时候
这个时候
它们能进行混合运算吗
比如说让整数和实数来做加法
那么这两个类型它就不一致
而加法运算符
要求参与运算的操作数
都是类型一致的
这个时候怎么办呢
这就出现一个类型转换问题
类型转换呢有隐含的转换
也叫引式转换
也有我们刻意在程序中
是指明要按这种方式转换的
那叫做显式的转换
接下来我给大家详细介绍
这部分内容
现在我们来看一下
这是一个运算符优先级的表
这个表里列出了
目前我们学过的
还包括一些没有学到的运算符
它的优先级
大家可以不用去背这个表
用多了你自然就记住了
需要的时候查阅一下就行了
这里面列出了它的优先级
以及结合信
结合信就是把它的运算次序
同级运算符从左向右
还是从右向左来计算
如果说我们在运算中
有不同类型的数据进行混合运算
这个时候就会发生
类型转换的问题
像算术运算符 关系运算符
逻辑运算符 位运算符
和赋值运算符
都要求两个操作数的类型要一致
如果在运算中
比如算术运算 关系运算中
如果你参与运算的操作数类型
是不一致的
那编译器首先就会根据
它各自的类型试图自动去进行
数据类型的转换
也就是我们说的隐含转换
隐含转换的基本原则呢
就是将第一类型的数据
转换为较高类型的数据
那么这里呢
我们列出了这些数据类型
由低到高的次序
所谓低类型呢
就是它表示数据范围
比较窄的类型
而高类型呢
就是它表示数据范围
比较宽的类型
那这个表里面呢
列出了隐含转换的一些条件
和情况
比如说有一个操作数
是long double类型的时候
那么另一个操作数
也会转化为long double类型
那不满足上述这个条件
且有一个操作数
是double类型的时候
另一个操作数
就转化为double类型等等
大家可以仔细看一下这个表
看一下隐含转换的
这些详细的规则
如果说我们要将一个
非布尔类型的算术值
赋值给布尔类型
那么算术值为0 结果就是false
否则如果这个算术值不为0
那结果就是true 就是真
反过来如果要将一个布尔值
赋值给非布尔类型的时候
布尔值flase被转换成0来赋值
布尔值true被转换成1来赋值
我们知道在C语言中呢
是没有布尔类型的
那在C语言中我们是用什么
是用0和1来表示逻辑值的假和真在C++中
有了布尔类型也要求
你在进行逻辑运算的时候
关系运算的时候
结果应该是布尔类型
但是由于这样一种自动的
转换的规则在C++中
仍然可以在需要布尔类型时候
去给它一个数值
或者在需要整数值的时候
去给它一个布尔类型
它们之间是可以转换
这样使得程序会非常灵活
当然对于不熟悉的初学者
有的时候也是给我们提供了
更多的出错的机会
大家用这种自动的转换要小心
而且要用得心理清楚明白
它在什么时候发生了
什么样的转换
那么如果浮点数跟整数之间
赋值的时候会怎么样呢
如果将一个浮点数赋值给
整数类型
那结果值就只保留
浮点数的整数部分
小数部分就被舍弃了
这个过程中不会发生舍入
不会发生四舍五入
就纯是把小数舍掉了
当把一个整数赋值给
浮点类型的时候
小数部分就记为0
整数部分就作为
浮点数的整数部分赋过去
除了隐式的类型转换呢
我们还可以用显式类型
转换的方式
显示类型转换在C++中
有三种形式
简单的形式
就直接写出类型说明符和表达式
那么括号括在表达式上
或者括在类型说明符上都可以
这样的形式是
是从C语言继承而来的
那么在C++中
建议使用C++的类型转换
那么C++类型转换方式呢
是要有类型转换操作符
后面尖括号里面给出类型说明符
然后括号里面给出表达式
那么类型转换操作符呢
可以是const cast
dynamic cast
reinterpret cast和static cast
那么我们目前初学的时候
用的比较多的呢是static cast
大家先学会用这个就可以了
它就是简单的将变量
从一个类型转换成另一个类型
显式的转换
有的时候也叫强制类型转换
其他的类型转换操作呢
在以后的内容和例题中
遇到了我会追一给大家介绍
那现在我们来看底下的例子
比如说这里要将这个z
变量的类型转换成int类型
这样三种写法是完全等价的
-导学
--第1章导学
-计算机系统简介
--计算机系统简介
--计算机系统简介 测试题
-计算机语言和程序设计方法的发展
--计算机语言和程序设计方法的发展 测试题
-面向对象的基本概念
--面向对象的基本概念 测试题
-程序的开发过程
--程序的开发过程
--程序的开发过程 测试题
-信息的表示和储存
--计算机的数字系统
--数据的编码表示
--信息的表示和储存 测试题
-实验指导
-导学
--第二章导学
-C++语言概述
--C++语言概述 测试题
-基本数据类型、常量、变量
--程序举例
--基本数据类型、常量、变量 测试题
-运算与表达式
--运算与表达式 测试题
-实验二:简单程序设计(上)
-数据的输入和输出
--数据的输入和输出
--数据的输入和输出 测试题
-选择结构
--if语句
--switch语句
--选择结构 测试题
-循环结构
--for语句
--循环结构 测试题
-自定义类型
--自定义类型
--自定义类型
-第2章小结
--第二章小结
-实验二:C++简单程序设计(下)
-导学
--导学
-函数定义
--函数定义
--函数定义 测试题
-函数调用
--例3-2
--例3-3
--例3-4
--例3-5
--例3-6
--函数调用 测试题
-嵌套与递归
--例3-9
--例3-10
--嵌套与递归 测试题
-函数的参数传递
--函数的参数传递
--函数的参数传递 测试题
-引用类型
--引用类型 测试题
-含有可变参数的函数
--含有可变参数的函数 测试题
-内联函数
--内联函数 测试题
-constexpr函数
--CONSTEXPR函数课后习题
-带默认参数值的函数
--带默认参数值的函数 测试题
-函数重载
--函数重载 测试题
-C++系统函数
--C++系统函数习题
-第3章小结
--第三章小结
-实验三(上)函数的应用
-实验三(下)函数的应用
-导学
--导学
-面向对象程序的基本特点
--面向对象程序的基本特点 测试题
-类和对象
--类和对象的定义
--类和对象 测试题
-构造函数
--构造函数基本概念
--委托构造函数
--复制构造函数
--构造函数 测试题
-析构函数
--析构函数
--析构函数 测试题
-类的组合
--类的组合
--类的组合程序举例
--前向引用声明
--类的组合 测试题
-UML简介
--UML简介
--UML简介课后习题
-结构体与联合体
--结构体与联合体 测试题
-枚举类
--枚举类
--枚举类 测试题
-第4章小结
--第四章小结
-实验四(上)
--实验四(上)
-实验四(下)
--实验四(下)
-导学
--导学
-标识符的作用域与可见性
--标识符的作用域与可见性 测试题
-对象的生存期
--对象的生存期
--对象的生存期 测试题
-类的静态成员
--类的静态成员 测试题
-类的友元
--类的友元 测试题
-共享数据的保护
--共享数据的保护 测试题
-多文件结构和预编译命令
--多文件结构和预编译命令 测试题
-第5章小结
--小结
-实验五
--实验五
-导学
--导学
-数组的定义与初始化
--数组的定义与使用
--一维数组应用举例
--数组的定义与初始化 测试题
-数组作为函数的参数
--数组作为函数的参数 测试题
-对象数组
--对象数组
--对象数组 测试题
-基于范围的for循环
-指针的定义和运算
--指针的定义和运算 测试题
-综合实例
--综合实例
-实验六(上)
--实验六上
-指针与数组
--指针数组
--指针与数组 测试题
-指针与函数
--指针类型的函数
--指向函数的指针
--指针与函数 测试题
-对象指针
--对象指针
--对象指针 测试题
-动态内存分配
--动态内存分配 测试题
-智能指针
--智能指针
-vector对象
--vector对象
--vector对象 测试题
-对象复制与移动
--移动构造
--对象复制与移动 测试题
-字符串
--C风格字符串
--string类
--字符串 测试题
-第6章小结
--第六章小结
-综合实例
--综合实例
-实验六(下)
--实验六(下)