【C语言】整型提升和算术转换

您所在的位置:网站首页 c语言转换数据类型 【C语言】整型提升和算术转换

【C语言】整型提升和算术转换

2023-12-24 17:10| 来源: 网络整理| 查看: 265

文章目录 整型提升表达式求值隐式类型转换数据类型及大小截断&提升代码示例1代码示例2代码示例3代码示例4 -sizeof 算术转换代码示例1表达式属性 结语

整型提升

要想知道什么是整型提升,那就要从表达式求值说起

表达式求值

表 达 式 求 值 的 顺 序 一 部 分 是 由 操 作 符 的 优 先 级 和 结 合 性 决 定

同 样,有 些 表 达 式 的 操 作 数 在 求 值 的 过 程 中 可 能 需 要 转 换 为 其 他 类 型

什么是表达式? 举个最简单的例子

int main() { int a=3; int b=5; int c = a + b * 7; //c的式子即为表达式 return 0; }

而C的整个式子就是一个表达式求值

在这之中,参与计算的两个变量以及结果变量都是int类型,并不需要进行整型提升

在我们日常编写代码的时候,编译器经常会有隐式类型转换

隐式类型转换

C的整型算术运算总是至少以缺省整型类型的精度来进行的

为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转化为普通整型,这种转换称为整型提升

float f =3.14 int num =f;

在上面这个代码中就有隐式类型转换,由float型转换为int型

但是会有精度的丢失

此时num为3

我们知道,不同数据类型的数据大小如下

数据类型及大小 char字符数据类型4byteshort短整型2byteint整型4bytelong长整型4(32), 8(64)long long长长整型8bytefloat单精度浮点型(实型)4bytedouble双精度浮点型(实型)8byte

可以看到,short类型和char类型的字节数都是小于int类型的

当我们将一个int类型的数据存放到char中时,会发生截断

截断&提升

把四个字节放在1个字节的内容中,截断,只保留一个字节

把数字5放入char类型中,5的4个字节的内容会被截断

示例

char a = 3; //00000000000000000000000000000011 为3的二进制 //00000011 -a

在char类型a中,只存放了3的后8位(1个字节)的内容

这就是截断的表现形式

在char类型数据的表达式求值中,就会发生整型提升

规则如下:

把最高位视为符号位进行提升,在a和b的8位码前加24个0或1

代码示例1 #include int main() { char a = 3; //00000000000000000000000000000011 为3的二进制 //00000011 -a char b = 127; //00000000000000000000000001111111 为127的二进制 //01111111 -b char c = a + b; //把最高位视为符号位进行提升 //在a和b的8位码前加24个0 //00000000000000000000000000000011 //00000000000000000000000001111111 //00000000000000000000000010000010 //10000010 为char c //11111111111111111111111110000010 -补码 //11111111111111111111111110000001 -反码 //10000000000000000000000001111110 -原码 // -126 //发现a和b都是char类型的,都没有达到一个int的大小 //这里就会发生整型提升 printf("%d\n", c);//%d是有符号数,打印原码 return 0; }

编译器中,负数是以补码的形式存放的

但在使用的时候,要先转换成原码再计算其数值

代码示例2

再来看一个比较大小的示例

int main() { char a = 0xb6; short b = 0xb600; int c = 0xb6000000; if(a==0xb6) printf("a"); if(b==0xb600) printf("b"); if(c==0xb6000000) printf("c"); return 0; }

猜猜打印结果是什么?

是这个吗?

a b c

错!

image-20211117204908103

运行后,我们会发现编译器只打印了c这个字符

因为if只会比较整型

而char和short类型都不足4个字节,在比较的时候需要进行整型提升

提升之后的结果与原数据不同

而int c本身就是整型,无须进行整型提升

int c = 0xb6000000;

所以代码只打印了字符c

代码示例3

再来看下面的这个代码,打印的结果是几呢?

#include int main() { int a = 3; int b = 5; short s = 5; printf("%u\n", sizeof(s = a + 3)); return 0; }

结果为2

因为最后的s是短整型,推断出来的长度为2

代码示例4 -sizeof int main() { char c=1; printf("%u\n",sizeof(c));//1 printf("%u\n",sizeof(+c));//4 printf("%u\n",sizeof(-c));//4 printf("%u\n",sizeof(!c));//4 return 0; }

当+c和-c参与计算的时候,就会进行整型提升

这里涉及到了另外一个重要的知识点,sizeof括号中表达式的问题

下篇博客会详细介绍!

算术转换

说完整型提升,接下来就是和隐式类型转换很像的算术转换

如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数转换为另外一个操作数的类型,否则操作就无法进行。

下面的层次体系称为寻常算术转换

long doubledoublefloatunsigned long intlong intunsigned intint

具体是怎么转换的呢?

在进行运算的时候,如果某个操作数的类型在上表中排名较低,那么首先要转换为另外一个操作数的类型后,再执行运算。

简单地说,就是从下往上转换

注意:算术转换要合理,不然会有潜在的问题

代码示例1

下面的是一个简单算术转换的示例

在int型和float类型一起计算的时候

int类型会转换为float类型进行计算

#include int main() { int a=3; float f =5.5; float ra =a+f; //算术转换,int-->float return 0; } 表达式属性

这里可以引出另外一个知识点,表达式的属性

表达式的两个属性:

值属性类型属性

如以下代码中

a+b的结果30就是这个表达式的指属性

类型属性是int

int main() { int a =10; int b=20; a+b;//表达式2个属性:值属性,类型属性 //30 值属性 //int 类型属性 return 0; } 结语

本篇博客到这里就结束了

如果对你有帮助的话,还请点个赞再走吧!

这对我非常重要!



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3