数据类型转换&「显式类型转换」&「隐式类型转换」(整型提升与截断)

目录

引入

隐式类型转换

整型提升

算数转换

显式类型转换


引入

类型转换

当使用一种类型代替另外一种类型进行操作时或者存在两个不同类型的对象进行操作时,首先就得进行类型的转换。而类型转换的方式一般可分为

  • 隐式类型转换(自动类型转换)

  • 显示类型转换(强制类型转换)

9134111b9d0241459726d4799f2541bd.png

那么他们究竟有何不同呢?


隐式类型转换

整型提升

定义

C语言中字节数少于整型字节数的数据类型在进行整型运算时,该类型的数据会被默认转为整型数据。

理解

运算器(ALU),其操作对象的字节大小被要求至少是int的字节数。数据在被运算时,数据并不是直接在ALU上存储的,而是存储在CPU的寄存器(register)中,而通用寄存器的字节大小与ALU操作数的字节大小保持一致。针对小于4byte的数据类型,会默认转化为整型数据

情况

在数据类型为char(1byte)/short(2byte)时,需要考虑整型提升。

char:

当数据在-128~127之间时,可以用8bits(1byte)表示,不需要整型提升。但当数据超过时候则需要。

unsigned char:

当数据在0~255之间,不需要考虑整型提升。

转化方法

  • 无符号数(unsigned char):低位不变,高位补符号位;

  • 有符号数(char):低位不变,高位补0。

例【1】

int main()
{
    char a=3;
    char b=127;
    char c=a+b;
    printf("%d",c);
}

打印的结果为-126。

理性分析:

截断存入a,b

a的补码为0000 0011

b的补码为0111 1111

运算时,整型提升

a的补码为0000 0000 0000 0000 0000 0000 0000 0011

b的补码为0000 0000 0000 0000 0000 0000 0111 1111

c的补码为0000 0000 0000 0000 0000 0000 1000 0010

截断

c的补码为1000 0010

输出

c的数据类型为char而非unsigned char,所以用有符号的整型提升方式

c的补码为1111 1111 1111 1111 1111 1111 1000 0010

c的反码为1111 1111 1111 1111 1111 1111 1000 0001

c的原码为1000 0000 0000 0000 0000 0000 0111 1110

针对原码,按照%d,即为有符号位的数字

c对应的数字为-126

例【2】

int main()
{
    char a=255;
    printf("%d",a);//-1
    printf("%u",a);//4294967295
}

截断存入

1111 1111

输出时,按有符号类型整型提升

255的补码1111 1111 1111 1111 1111 1111 1111 1111

255的反码1111 1111 1111 1111 1111 1111 1111 1111

255的原码1111 1111 1111 1111 1111 1111 1111 1111

  • 按%d输出-1

  • 按%u输出4294967295

隐式类型转换总结

  • 存入数据时(char a=-1;char b=255):存入补码,按照数据类型进行截断,例如char,则只保留8个bit

  • 计算数据时(char c=a+b):按照原数据类型进行整型提升,然后用补码相加减,再次截断存入(8位)

  • 输出数据时(printf("%d/%u")):按照原数据类型进行整型提升,经过反码转化为原码(32位),最后根据%d/%u输出数据

算数转换

上面提到的均为所占内存大小小于int类型的情况?那其他情况呢?

寻常算数转换的方向:


double ←── float 高

long

↑ unsigned

↑ int ←── char,short 低


例【3】

int main()
{
    int i=-1;
    if(i<sizeof(i))
    {
        printf("-1<4?");
    }
    if(i>sizeof(i))
    {
        printf("-1>4?");
    }
}

让人意外的是最后输出的结果是-1>4?

这是什么原因呢?我们分析一下:

  • 第一感觉最有可能出问题的就是这里的sizeof。
  • sizeof这个运算符的返回类型是size_t,是unsigned int 的一种。所以在sizeof(i)时,i从int转化成为了unsigned int。
  • -1的补码是一长串1,所以可想而知转化为无符号类型(unsigned int)数据会变得非常之大,因此这个结果也就合理了。

显式类型转换

格式:(强制转换的类型)表达式

int main()
{
    int a=(int)3.14;
    printf("%d",a);
    最后输出结果位3
}

再看下面这个例子,是否强制类型转换也会影响最后的结果:

ec35db2e4dc74bf882ba45b0709c0c37.png

  • mean1:17/5 中两个操作数均为整型,最后的结果是一个去除小数部分的整数3,再用float类型输出,变为3.000000

  • mean2:其中的17转化为double类型,实际上是17.000000/5结果也就自然会多出这个0.400000


以上就是本篇博客的全部内容

  • 11
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值