隐式类型转换

目录

 

前言

一、赋值转换

二、运算转换

2.1 - 整型提升


 


前言

在 C 语言中,类型转换的方式一般可分为隐式类型转换显示类型转换(也称为强制类型转换)。其中隐式类型转换由编译器自动进行,不需要程序员干预。

隐式类型转换通常有两种情况:赋值转换运算转换

 

一、赋值转换

将一种类型的数据赋值给另外一种类型的变量时,发生隐式类型转换。例如:

double pi = 3.14;
int num = pi;

在对变量赋值时,若等号两边的数据类型不同,需要把右边表达式的类型转换为左边变量的类型,这可能导致数据失真(精度降低),所以隐式类型转换不一定安全。  

 

二、运算转换

C 语言中不同类型的数据需要转换成同一类型,才可以计算。转换规则如下:

  • 转换按照数据长度增加的方向进行,以保证精度不降低。比如 int 类型的数据和 double 类型的数据相加时,int 类型的数据就会被隐式地转换成 double 类型,然后再进行运算。

  • 如果两种类型的字节数一样,且一种有符号,另一种无符号,则转换成无符号类型

  • char 类型和 short 类型参与运算时,必须先转换成 int 类型(整型提升)

示例

#include <stdio.h>

int main()
{
	int num = -1;
	printf("%d\n", sizeof(num));  // 4
	if (num < sizeof(num))
		printf("num < sizeof(num)\n");
	else
		printf("num >= sizeof(num)\n");
	return 0;
}

输出结果:num >= sizeof(num),这是因为 num 的类型是 int,而 sizeof(num) 的返回值类型是 unsigned int,因此在比较运算中,num 被隐式地转换成了 unsigned int。

 

2.1 - 整型提升

整型提升(integral promotion)是 C 程序设计语言中的一项规定:在表达式计算时,各种整型首先要提升为 int 类型,如果 int 类型不足以表示,则要提升为 unsigned int 类型,然后执行表达式的运算。例如,C 语言标准中仅规定了 char 的长度 <= short 的长度 <= int 的长度,这意味着在 short 与 int 的长度相等的情况下,unsigned short 就无法提升为 int,只能提升为 unsigned int。

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

注意:整型提升是有符号补符号位,无符号则补 0

示例一

#include <stdio.h>

int main()
{
	char a = 3;
	// 00000000 00000000 00000000 00000011(3 的补码)
	// 截断:
	// 00000011(a 的补码)
	char b = 127;
	// 00000000 00000000 00000000 01111111(127 的补码)
	// 截断:
	// 01111111(b 的补码)
	char c = a + b;
	// 表达式计算时,需要进行整型提升,即:
	// 00000000 00000000 00000000 00000011
	// +
	// 00000000 00000000 00000000 01111111 
	// =
	// 00000000 00000000 00000000 10000010
	// 截断:
	// 10000010(c 的补码)
	printf("%d\n", c);
	// %d 是 int 类型数据的占位符,因此要进行提升,即:
	// 11111111 11111111 11111111 10000010
	// 10000000 00000000 00000000 01111110(原码 ==> -126)
	return 0;
}

示例二

#include <stdio.h>

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");
	// char 类型的变量 a 和 short 类型的变量 b 在参与表达式计算时被提升为 int 类型,分别为:
	// 11111111 11111111 11111111 10110110,即 0xffffffb6
	// 11111111 11111111 10110110 00000000,即 0xffffb600
	// int 类型的变量 c 没有进行整型提升,因此输出的结果是 c。
	if (a == 0xffffffb6)
		printf("hehe\n");
	if (b == 0xffffb600)
		printf("haha\n");
	// 输出 hehe 和 haha
	return 0;
}

示例三

#include <stdio.h>

int main()
{
	char a = 1;
	printf("%zd\n", sizeof(a));  // 1
	printf("%zd\n", sizeof(+a));  // 4
	printf("%zd\n", sizeof(-a));  // 4
	// char 类型的变量 a 作为 +/- 的操作数参与运算时,需要进行整型提升
	return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值