C语言对类型的转换

本文详细解释了C语言中整形提升、截断和算数转换的规则,包括不同类型数据运算时的转换机制,以及整形提升如何利用CPU资源。还讨论了整形提升可能导致的问题和不同类型之间的算数转换优先级。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C语言对类型的转换


我们都知道,C语言中内置了多种整形类型,占用空间从大到小,基本满足各类使用场景(比如超长数字的运算就不属此范畴),当程序对大小小于 int 类型的整形进行调用或是储存时,会发生整形提升和截断,当不同类型的数据进行计算时,会发生算数转换

整形提升和截断

整形提升

在C程序中,整形的算术运算总是以缺省(默认)整形类型进行运算的,即使用 int 类型进行运算。因此,在使用 char 等长度小于 int 的类型进行计算时,会发生整形提升。

整形提升规则

对于 signed 类型,高位补充符号位

对于 unsigned 类型,高位补0

注意 整形提升和截断均是对补码的操作

int main()
{
	char a = -1;
	//此时a为 10000001
	//求补码:11111111
	char b = 4;
	//b:00000100

	//此时对a,b进行调用
	char c = 0;
	c = a + b;
	//发生整形提升
	//		  a:11111111 11111111 11111111 11111111
	//		  b:00000000 00000000 00000000 00000100
	//   相加:(1)00000000 00000000 00000000 00000011
	//    0x       00       00       00       03
	 
	return 0;
}

如打印、计算等操作都会发生整形提升

整形提升的意义

通过整形提升,可以对CPU中的运算器件进行复用

对于大多数现代的 CPU 架构来说,整数运算器通常会以特定的字长(word length)为单位进行计算。这个字长通常是指 CPU 寄存器的位数,比如32位或64位,当CPU为32位时,会以 int 为单位进行计算

因此,即使是两个 char 类型的计算,也要转换成两个 int 类型之间的计算。即先转换成 int ,再进行运算

当一个表达式中包含了大于 int 的类型时,宽度超过了 CPU 字长,在运算时需要进行额外的处理,比如拆分成多个操作数进行运算、进行额外的位操作等

截断

以上面这段代码为例,得到的 c 仍旧为 4 bytes ,显然无法存入 char,此时发生截断

截断规则

从低位开始,按照存入空间的大小对整形进行截断,保留低位,丢弃高位

如 char c = 00000011


以下是一个对整形提升和截断的规则进行解析的例子

//使用不当时,整形提升和截断也会造成一些问题
#include <stdio.h>
int main()
{
    char a = -128;
    // 10000000 00000000 00000000 10000000
    // 11111111 11111111 11111111 01111111
    // 11111111 11111111 11111111 10000000
    // 截断,存入a
    // 10000000 -- a
    
    
    // 整形提升,有符号数,高位补1
    // 11111111 11111111 11111111 10000000
    // 打印无符号
    printf("%u\n", a);
    //4294967168
    // %u - 打印无符号整数

    printf("%d\n", a);
    // 11111111 11111111 11111111 10000000
    // 认为是负数,求原码
    // 10000000 00000000 00000000 01111111
    // 10000000 00000000 00000000 10000000
    // -128
    return 0;
}

算数转换

当不同类型的整形之间进行运算时,需要将整形转换为同一类型后进行计算

下面这个表格中位置较低的类型,在遇到位置较高的类型时,会发生算数转换

类型
long double
double
float
unsigned long
long
unsigned int
int
short
char

long long 和 long double 的优先级尚不明确(我还没有找到明确解析)

long double 在 C99 标准中被引入,用以表示更高精度的浮点数

长度可能会应编译器和平台的不同而产生差异,可能和 double 一样长,可能更长(8/12/16Bytes)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值