关于整型提升(C语言隐式类型转换)

C语言整型提升(隐式类型转换)

定义

  C的整型算术运算总是至少以缺省整型类型的精度来进行的。为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升 (integral promotion)。

这一规则是由C语言的发明人丹尼斯·里奇肯·汤普逊创设的 (原话如下)

“A character, a short integer, or an integer bit-field, all either signed or not, or an object of enumeration type, may be used in an expression wherever an integer maybe used. If an int can represent all the values of the original type, then the value is converted to int; otherwise the value is converted to unsigned int. This process is called integral promotion.”

翻译:“ 表达式中可以使用整数的地方,就可以使用枚举类型,或有符号或无符号的字符、短整数、整数位域。 如果一个 int 可以表示原始类型的所有值,则将该值转换为 int; 否则该值将转换为无符号整数。 这个过程叫做整型提升。”

  

整型提升的意义

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

//例1:
    char a,b,c;
    a = b + c;	

b, c的值被提升为普通整型进行加法运算。但是运算结果会被截断再存储到a中。

//例2: 关于结果截断更明显的示例
    unsigned char a = 0;
	unsigned char b = 255;
	unsigned char c = 255;
	a = b + c;         //无符号
	printf("%u\n", a);

截断
在这里插入图片描述

  

整型提升

整型提升是按照变量的数据类型 (变量本身的数据类型) 的符号位进行提升。

//正数整型提升
char a = 1;
a在内存中为(二进制补码):0000 0001
因为 char 有符号符号位为0,所以整型提升由8个bit到32个bit:
0000 0000 0000 0000 0000 0000 0000 0001
  
//负数整型提升
char a = -1;
a在内存中为(二进制补码):111 1111
因为 char 有符号符号位为1,所以整型提升由8个bit到32个bit:
1111 1111 1111 1111 1111 1111 1111 1111

例题:
int main()
{
	char a = 0xb6;
	short b = 0xb600;
	int c = 0xb6000000;
	if (a == 0xb6)
		printf("a\n");
	if (b == 0xb600)
		printf("b\n");
	if (c == 0xb6000000)
		printf("c\n");
	return 0;            //输出结果为 c
}

0xb6的二进制补码为 1011 0110因为char是有符号,等于运算整型提升补1,结果不等于0xb6,为假。

  

//特例:
int main()
{
    char c = 1;
    printf("%u\n", sizeof(c));
    printf("%u\n", sizeof(+c));
    printf("%u\n", sizeof(!c));
    return 0;
}

c只要参与表达式运算,就会发生整形提升,表达式 +c ,就会发生提升,所以 sizeof(+c) 是4个字节;但(!c)是否整型提升跟编译器有关,有待研究。

V S 2013运行截图在这里插入图片描述
Dev C++运行截图
在这里插入图片描述

  

算术转换

在这里插入图片描述

练习:

1、如下代码输出的是什么( )

char a=101; 
int sum=200;
a+=27;sum+=a;
printf("%d\n",sum);

解析:
a+=27后溢出a=-128:
a=127时补码为 0111 1111
a+=1时-128的补码为: (1)1000 0000 ,(因为char类型只有1字节,8bits ,所以其中最高位的1溢出)。
sum 为 int 型,sum = sum + a,a会整型提升为32bits,按照整形提升规则补1:
1111 1111 1111 1111 1111 1111 1000 0000
sum为200,补码为:0000 0000 0000 0000 0000 0000 1100 1000
所以 sum = sum + a
=0000 0000 0000 0000 0000 0000 1100 1000 + 1111 1111 1111 1111 1111 1111 1000 0000
= (1)0000 0000 0000 0000 0000 0000 0100 1000 = 72
溢出
在这里插入图片描述

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值