【C语言初阶】隐式类型转换

【C语言初阶】隐式类型转换

1 隐式类型转换

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

1.1 整型提升

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

1.2 整型提升的意义

表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长度一般是一个 int 的字节长度,同时也是CPU中通用寄存器的长度。

因此,即使两个char类型的对象相加,在CPU执行时也要事先转换为CPU内整型操作数的标准长度。

通用CPU(general-purpose CPU)是难以直接实现两个8比特字节直接进行相加的运算。所以,表达式中各对象的长度可能小于 int 长度的整型值,都必须先转换为 intunsigned int ,然后才能送去CPU执行型运算。


1.3 示例1

代码示例

#include<stdio.h>

int main()
{
	//整型提升示例1

	char a = 0, b = 0, c = 0;
	a = b + c;
	//在执行b+c运算时,先将b和c的值提升为整型,然后再进行加法运算
	//加法运算执行完后,由于a是字符型,赋的值为整型,存储时会发生截断

	return 0;
}

解释说明

1 进行加法运算时,如果操作数是 char 类型的,就会发生整型提升

2 整型数值赋给字符型变量时会发生截断


1.4 如何进行整型提升?

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

1.4.1 负数的整型提升

代码示例

#include<stdio.h>

int main()
{
	//负数的整型提升
	char ch = -1;
	//00000000 00000000 00000000 00000001  --  1的补码(原码)
	//10000000 00000000 00000000 00000001  --  -1的原码
	//11111111 11111111 11111111 11111110  --  -1的反码
	//11111111 11111111 11111111 11111111  --  -1的补码
	//int型数据存放到char型变量中,会发生截断,取低8位二进制
	//11111111  --  补码形式,符号位为1

	//如何进行整型提升
	//char为有符号的char,在整型提升的时候,高位补充符号位,此处符号位为1
	//11111111 11111111 11111111 11111111  --  整型提升后的结果,是一个负数的补码

	return 0;
}

解释说明

1 在整型提升时,高位用符号位的值来填充。


1.4.2 正数的整型提升

代码示例

#include<stdio.h>

int main()
{
	//正数的整型提升

	char a = -1;
	//11111111 11111111 11111111 11111111  --  -1的补码
	//整型值存储到char型变量时会发生截断:
	//11111111
	signed char b = -1;
	//11111111
	unsigned char c = -1;
	//11111111

	printf("a = %d,b = %d,c = %d\n", a, b, c);//-1 -1 255
	//a为有符号的char,在整型提升的时候,高位补充符号位,此处符号位为1
	//整型提升
	//11111111 11111111 11111111 11111111  负数的补码
	//11111111 11111111 11111111 11111110  负数的反码
	//10000000 00000000 00000000 00000001  负数的原码  --  -1的原码 
	//
	//b为有符号的char,在整型提升的时候,高位补充符号位,此处符号位为1
	//整型提升
	//11111111 11111111 11111111 11111111  负数的补码
	//11111111 11111111 11111111 11111110  负数的反码
	//10000000 00000000 00000000 00000001  负数的原码  --  -1的原码 
	//
	//c为无符号的char,无符号数进行整型提升的时候,高位补0
	//整型提升
	//00000000 00000000 00000000 11111111  正数的补码
	//00000000 00000000 00000000 11111111  正数的原码  --  255的原码

	return 0;
}

解释说明

1 无符号数在进行整型提升的时候,高位补0


1.5 示例2

代码示例

#include<stdio.h>

int main()
{
	//整型提升示例2

	char a = 0xb6;
	//0xb6是一个十六进制数,每4位二进制数表示1个十六进制数
	//b    6
	//1011 0110
	//00000000 00000000 00000000 10110110  --  0xb6的补码(原码)
	//整型值存储到char型变量时会发生截断,一个char变量占8个bit位
	//10110110  --  补码形式,符号位为1

	short b = 0xb600;
	//0xb600是一个十六进制数,每4位二进制数表示1个十六进制数
	//b    6    0    0   
	//1011 0110 0000 0000
	//00000000 00000000 10110110 00000000  --  0xb600的补码(原码)
	//整型值存储到short型变量时会发生截断,short型为16个bit位
	//10110110 00000000  --  补码形式,符号位为1

	int c = 0xb6000000;
	//10110110 00000000 00000000 00000000 00000000 -- 0xb6000000的补码(原码)

	//进行表达式计算时,变量a的类型是char类型,此时会发生整型提升
	if (a == 0xb6)
	{
		//a存储的值:10110110
		//10110110  --  补码形式,符号位为1
		//a为有符号的char,在整型提升的时候,高位补充符号位,此处符号位为1
		//
		//发生整型提升:
		//11111111 11111111 11111111 10110110  --  整型提升后的结果,是一个负数的补码
		//00000000 00000000 00000000 10110110  --  0xb6的补码(原码)
		//结果明显不相同,判断为假
		//
		printf("a\n");//不打印
	}
	if (b == 0xb600)
	{
		//b存储的值:10110110 00000000
		//10110110 00000000  --  补码形式,符号位为1
		//b为有符号的short,在整型提升的时候,高位补充符号位,此处符号位为1
		//
		//发生整型提升:
		//11111111 11111111 10110110 00000000  --  整型提升后的结果,是一个负数的补码
		//00000000 00000000 10110110 00000000  --  0xb600的补码(原码)
		//结果明显不相同,判断为假
		//
		printf("b\n");//不打印
	}
	if (c == 0xb6000000)
	{
		//c为整型,不发生整型提升
		//
		printf("c\n");//打印输出
	}
	//最终打印输出结果为:c

	return 0;
}

解释说明

详解见上述代码中的注释内容。


1.6 示例3

代码示例

#include<stdio.h>

int main()
{
	//整型提升示例3

	char c = 1;
	printf("%u\n", sizeof(c));//1
	printf("%u\n", sizeof(+c));//4
	printf("%u\n", sizeof(-c));//4
	
	//sizeof求值返回的是size_t类型的值
	//size_t <==> unsigned int
	//%u -- 以十进制形式打印无符号整数

	return 0;
}

解释说明

1 +c-c是表达式,会进行计算求值;而 c 的类型为 char表达式求值时会发生整型提升

  对操作数进行整型提升后,sizeof 计算的值就为 int 型的值

2 cchar 类型的变量,如果参与了表达式运算,就会发生整型提升


2 算术转换

如果某个操作符的各个操作数属于不同的数据类型,那么只有较低数据类型向较高数据类型进行隐式类型转换,彼此间才能进行运算。

2.1 寻常算术转换

示例

long double
double
float
unsigned long int
long int
unsigned int
int

说明

1 上述所示数据类型,如果某个操作数的类型排名较低,那么首先要转换为另一个操作数的类型,然后再进行运算

2 上述类型,由低向高( int -> long double )进行算术转换

注意

应避免较高类型向较低类型的转换

float f = 3.14f;
int num = f;//隐式类型转换,会丢失精度


总结:

  本节介绍了隐式类型转换中的整型提升和算术转换,同时给出了相关代码以及详细注释。


感谢您的阅读!如有任何错误,欢迎您的批评指正!

  • 24
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值