目录
前言
一、赋值转换
二、运算转换
2.1 - 整型提升
在 C 语言中,类型转换的方式一般可分为隐式类型转换和显示类型转换(也称为强制类型转换)。其中隐式类型转换由编译器自动进行,不需要程序员干预。
隐式类型转换通常有两种情况:赋值转换和运算转换。
将一种类型的数据赋值给另外一种类型的变量时,发生隐式类型转换。例如:
double pi = 3.14;
int num = pi;
在对变量赋值时,若等号两边的数据类型不同,需要把右边表达式的类型转换为左边变量的类型,这可能导致数据失真(精度降低),所以隐式类型转换不一定安全。
C 语言中不同类型的数据需要转换成同一类型,才可以计算。转换规则如下:
转换按照数据长度增加的方向进行,以保证精度不降低。比如 int 类型的数据和 double 类型的数据相加时,int 类型的数据就会被隐式地转换成 double 类型,然后再进行运算。
如果两种类型的字节数一样,且一种有符号,另一种无符号,则转换成无符号类型。
char 类型和 short 类型参与运算时,必须先转换成 int 类型(整型提升)。
示例:
#include
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。
整型提升(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
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
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
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;
}