隐式类型转换(整形提升)

1:什么是整形提升?

整形提升是指在C语言中,当较小的整数类型(如charshort)参与表达式运算时,它们会被自动提升为较大的整数类型(如intunsigned int)的过程。

整形提升是由C语言标准规定的隐式类型转换规则。当较小的整数类型参与表达式运算时,它们会被自动提升为较大的整数类型,以便进行一致的计算。这样做是为了避免在计算过程中出现意外的精度丢失或溢出。

例如,当一个char类型的变量和一个int类型的变量进行运算时,char类型的变量会被提升为int类型,然后再进行运算。这种提升是隐式进行的,程序员无需手动指定。

 简单来说,char为1个字节,short为2个字节,他们在参与各个运算时都会系统隐式转换为int类型,4个字节

2:整形提升的意义:

表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长度
一般就是int的字节长度,同时也是CPU的通用寄存器的长度。
因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长度。通用CPU(general-purpose CPU)是难以直接实现两个8比特字节直接相加运算(虽然机器指令中可能有这种字节相加指令)。所以,表达式中各种长度可能小于int长度的整型值,都必须先转换为int或unsigned int,然后才能送入CPU去执行运算。 

 //实例1
char a,b,c;
...
a = b + c;

 b和c的值被提升为普通整型,然后再执行加法运算,加法运算完成之后,结果将被截断,然后再存储于a中。

 3:如何进行整形提升?

 整形提升是按照变量的数据类型的符号位来提升的

有符号整数提升,高位补符号位,无符号整数提升,高位补0 

//负数的整形提升
char c1 = -1;
变量c1的二进制位(补码)中只有8个比特位:1111111
因为 char 为有符号的 char,所以整形提升的时候,高位补充符号位,即为1
提升之后的结果是:
11111111111111111111111111111111
//正数的整形提升
char c2 = 1;
变量c2的二进制位(补码)中只有8个比特位:00000001
因为 char 为有符号的 char
所以整形提升的时候,高位补充符号位,即为0
提升之后的结果是:
00000000000000000000000000000001
//无符号整形提升,高位补0 

4:整形提升的实例: 

例一:

#include<stdio.h>
int main()
{
    char a = 3;
    char b = 127;
    char c = a + b;
    printf("%d\n", c);
    return 0;
}
这个例子能很经典的说明整形提升。首先,它的结果为:

原因: a为char类型,一个字节,3为int类型,4个字节,当3赋给a时,

3在内存中的二进制:00000000000000000000000000000011存储到a中会发生截断,

存储在a中的是:00000011

同理127在内存中的二进制:00000000000000000000000001111111存储到b中会发生截断,

存储在b中的是: 01111111

而char c=a+b这个表达式中,首先会计算a+b,然后再把值赋给c。

对于a+b的运算,因为a,b是有符号的char类型,小于int类型,相加时会发生整形提升,各自先变成整形。

所以a在内存中的二进制会变为: 00000000000000000000000000000011

所以b在内存中的二进制会变为: 000000000000000000000000001111111

相加得到  a+b                          :  00000000000000000000000010000010

再将a+b赋值给char类型的c时会发生截断,

得到c:10000010

在打印时,因为是%d打印(按十进制整形打印)所以c会整形提升

因为char是有符号的char,高位为符号位,补符号位1.

所以在内存中打印时,它变为:11111111111111111111111110000010(补码)。

它的原码是                             :10000000000000000000001111110 (补码取反再加1得到原码)                                      //即-126

所以打印时得到-126!

例二:

int main()
{
char c = 1;
printf("%u\n", sizeof(c));
printf("%u\n", sizeof(+c));
printf("%u\n", sizeof(-c));
return 0;
}

实例1中的,c只要参与表达式运算,就会发生整形提升,表达式 +c ,就会发生提升,所以 sizeof(+c) 是4个字节.表达式 -c 也会发生整形提升,所以 sizeof(-c) 是4个字节,但是 sizeof(c) ,就是1个字节.

 例三:

int main()
{
char a = 0xb6;//十进制为186
short b = 0xb600;//十进制为46592
int c = 0xb6000000;
if(a==0xb6)
printf("a");
if(b==0xb600)
printf("b");
if(c==0xb6000000)
printf("c");
return 0;
}

输出结果:c 

原因: 

char a = 0xb6;将一个十六进制值整数0xb6赋给了一个char类型的变量a。在C语言中,char类型是一个整数类型,它通常占用1个字节的内存空间,可以表示-128到127(如果是有符号的)或者0到255(如果是无符号的)范围内的整数值。

在这种情况下,0xb6是一个8位的十六进制整数,

0xb6在内存中的二进制是:00000000000000000000000010110110

放在char类型(因为char是有符号类型,高位为符号位)中会发生截断,所以a中存储的是:              10110110(补码)

它的原码为:11001010     即-74。

所以a中存储的是-74,并非0xb6即186,同理b中存储的也是一个负数,并非0xb600,而对于int类型的变量c,它不需要提升,因为它本身就是int类型。

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值