目录

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

类型转换从下到上转换