[toc]
整型提升
要想知道什么是整型提升,那就要从表达式求值说起
表达式求值
表 达 式 求 值 的 顺 序 一 部 分 是 由 操 作 符 的 优 先 级 和 结 合 性 决 定
同 样,有 些 表 达 式 的 操 作 数 在 求 值 的 过 程 中 可 能 需 要 转 换 为 其 他 类 型
什么是表达式? 举个最简单的例子
1 | int main() |
而C的整个式子就是一个表达式求值
在这之中,参与计算的两个变量以及结果变量都是int类型,并不需要进行整型提升
在我们日常编写代码的时候,编译器经常会有隐式类型转换
隐式类型转换
C的整型算术运算总是至少以缺省整型类型的精度来进行的
为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转化为普通整型,这种转换称为整型提升
1 | float f =3.14 |
在上面这个代码中就有隐式类型转换,由float型转换为int型
但是会有精度的丢失
此时num为3
我们知道,不同数据类型的数据大小如下
数据类型及大小
char | 字符数据类型 | 4byte |
---|---|---|
short | 短整型 | 2byte |
int | 整型 | 4byte |
long | 长整型 | 4(32), 8(64) |
long long | 长长整型 | 8byte |
float | 单精度浮点型(实型) | 4byte |
double | 双精度浮点型(实型) | 8byte |
可以看到,short类型和char类型的字节数都是小于int类型的
当我们将一个int类型的数据存放到char中时,会发生截断
截断&提升
把四个字节放在1个字节的内容中,截断,只保留一个字节
把数字5放入char类型中,5的4个字节的内容会被截断
示例
1 | char a = 3; |
在char类型a中,只存放了3的后8位(1个字节)的内容
这就是截断的表现形式
在char类型数据的表达式求值中,就会发生整型提升
规则如下:
把最高位视为符号位进行提升,在a和b的8位码前加24个0或1
代码示例1
1 |
|
编译器中,负数是以补码的形式存放的
但在使用的时候,要先转换成原码再计算其数值
代码示例2
再来看一个比较大小的示例
1 | int main() |
猜猜打印结果是什么?
是这个吗?
1 | a |
错!
运行后,我们会发现编译器只打印了c这个字符
因为if只会比较整型
而char和short类型都不足4个字节,在比较的时候需要进行整型提升
提升之后的结果与原数据不同
而int c本身就是整型,无须进行整型提升
1 | int c = 0xb6000000; |
所以代码只打印了字符c
代码示例3
再来看下面的这个代码,打印的结果是几呢?
1 |
|
结果为2
因为最后的s是短整型,推断出来的长度为2
代码示例4 -sizeof
1 | int main() |
当+c和-c参与计算的时候,就会进行整型提升
这里涉及到了另外一个重要的知识点,sizeof括号中表达式的问题
下篇博客会详细介绍!
算术转换
说完整型提升,接下来就是和隐式类型转换很像的算术转换
如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数转换为另外一个操作数的类型,否则操作就无法进行。
下面的层次体系称为寻常算术转换
long double |
---|
double |
float |
unsigned long int |
long int |
unsigned int |
int |
具体是怎么转换的呢?
在进行运算的时候,如果某个操作数的类型在上表中排名较低,那么首先要转换为另外一个操作数的类型后,再执行运算。
简单地说,就是从下往上转换
注意:算术转换要合理,不然会有潜在的问题
代码示例1
下面的是一个简单算术转换的示例
在int型和float类型一起计算的时候
int类型会转换为float类型进行计算
1 |
|
表达式属性
这里可以引出另外一个知识点,表达式的属性
表达式的两个属性:
- 值属性
- 类型属性
如以下代码中
a+b的结果30就是这个表达式的指属性
类型属性是int
1 | int main() |
结语
本篇博客到这里就结束了
如果对你有帮助的话,还请点个赞再走吧!
这对我非常重要!
- 本文标题:【C语言】整型提升和算术转换
- 创建时间:2021-11-17 14:14:28
- 本文链接:posts/3918217186/
- 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!