C语言强制类型转换
C语言类型转换
隐式转换
C的整数运算是以int类型来进行的,如果精度不够的话,eg:short类型,char类型做整数运算,将其提升为int类型做运算。
int类型也被称为缺省类型。
为了获取int类型的精度,表达式中的char和short类型操作数在使用之前,先被转换为int类型,这中被称为整形提升
整形提升的意义
表达式的整形运算要在CPU的相应运算器件内执行,CPU内整形运算器(ALU)的操作数的字节长度一般是int的字节类型,同时也是CPU的通用寄存器的长度。
因此,两个char类型相加,在CPU执行时实际上也要先转换为CPU内整形操作数的标准长度。
通用CPU(general-purpose CPU)是难以直接实现两个8比特字节直接相加运算(虽然机器指令中可能有这种字节相加指令)。所以,表达式各种长度可能小于int长度的整型值,都必须先转换为int或unsigned int,然后才能送去CPU执行运算。
如何进行整形提升呢?
整形提升是按照变量的数据类型的符号位来提升的
负数的整形提升
char c1 = -1;
变量c1的二进制位(补码)中只有8个比特位:11111111
因为char类型是有符号的char,所以整形提升的时候,高位补充符号位,即为1
提升之后的结果是:11111111111111111111111111111111
正数的整形提升
char c2 = 1;
变量c1的二进制位(补码)中只有8个比特位:00000001
因为char类型是有符号的char,所以整形提升的时候,高位补充符号位,即为0
提升之后的结果是:00000000000000000000000000000001
#include <stdio.h>
int main(void)
{
char a = 3;
// 00000011 = 3 ---> 整形提升 00000000000000000000000000000011
char b = 127;
// 01111111 = 127 ---> 整形提升 00000000000000000000000001111111
char c = a + b;
// 00000000000000000000000000000011
// 00000000000000000000000001111111
// 00000000000000000000000010000010 = c 这是补码
// 要存储在char类型中,所以要截断:10000010
// 在printf()函数中%d返回的int类型的值,所以要整形提升,补充符号位为
// 11111111111111111111111110000010 ---> 这是补码
// 11111111111111111111111110000001 补码-1求出反码
// 10000000000000000000000001111110 = -126 反码按位取反,求出原码
printf("%d\n", c); // -126
return 0;
}
注:二进制的第n位 = 第n-1位的和+1
整型提升对数值比较的影响
#include <stdio.h>
int main(void)
{
char a = 0xb6;
short b = 0xb600;
int c = 0xb6000000;
// 在对比时出现整形提升,所以打印c
if (a == 0xb6)
{
printf("a");
}
if (b == 0xb600)
{
printf("b");
}
if (c == 0xb6000000)
{
printf("c");
}
return 0;
}
整型提升对sizeof的影响
#include <stdio.h>
int main(void)
{
char c = 1;
printf("%d\n", !c); // 0
printf("%u\n", sizeof(c)); // 1
printf("%u\n", sizeof(+c)); // 4
printf("%u\n", sizeof(-c)); // 4
printf("%u\n", sizeof(!c)); // 4
return 0;
}
注:sizeof返回的是无符号的整形,应该使用%u来接受
算数转换
类型转换除了有隐式转换,还有算数转换
如果操作符的各个操作数不是一个类型,那么就需要将其中的一个类型转换为另一个类型,保持操作数的类型统一,不然操作就无法进行
long double
double
float
unsigned long int
long int
unsigned int
int
类型转换从下到上转换