C语言字节数据类型转换
最近总是遇见取数组做位运算的情况,每次都感觉上次学的忘记了...
浅写记录一下
数值的表示
(暂时没涉及到小数,所以目前写的都按照整数)
整数有正负之分,因此数值表示分为符号位和数值位,根据不同精度也分出了char short long等数据类型。
数值表示包括符号位和数值位。
正数符号位为0,原码、反码和补码相同,
负数符号位为1,原码为符号位加绝对值的二进制表示,反码为符号位不变,数值位取反。补码为反码加一。
众所周知,在实际使用过程中有些量可能根本不需要是负数,因此也有unsigned这一前缀来丰富数据类型,即不需要符号位。
【这一点非常关键,这决定了同样的编码在不同的数据类型下到底是几?】
注意:无符号类型没有符号位,全都是非负数。
数据类型的转换
-
无符号到有符号的转换
当从一个无符号整数类型转换为一个有符号整数类型时,数值的二进制表示不会改变,但解释方式会发生变化。如果转换后的值超出了目标类型的正数范围,则该值将被视为负数。
一个 UINT8 值 0xFF(即十进制255),将其转换为 INT16:二进制表示为 00000000 11111111。转换为 INT16 后,这个值仍然是 0x00FF,但是由于它在 INT16 的正数范围内(0 到 32767),所以它的值保持为255。然而,如果将 0xFF(255)直接转换为 INT8:二进制表示为 11111111。在 INT8 中,最高位是符号位,因此 11111111 表示的是 -1(因为这是 -128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = -1)。 -
有符号到无符号的转换
当从一个有符号整数类型转换为一个无符号整数类型时,同样地,数值的二进制表示不会改变,但解释方式会变。任何负数都会被解释为一个很大的正数。
一个 INT8 值 -1,其二进制补码表示为 11111111。将其转换为 UINT8 后,这个值变成255。 -
不同位宽之间的转换
当在不同位宽的整数类型之间转换时,可能会发生截断或符号扩展:
从较小位宽转换到较大位宽:较小的类型可以安全地转换为较大的类型,而不会丢失信息。对于有符号整数,符号位会被复制以填充新的高位(称为符号扩展)。对于无符号整数,高位被填充为0。
从较大位宽转换到较小位宽:这可能导致截断。超出目标类型范围的高阶位将被丢弃,只保留低阶位。这意味着较大的值可能会被截断成一个小得多的值,或者负数可能会变成一个大正数。
注意:不同的平台字节顺序不一样
字节顺序是指多字节数据类型(如 short、int、long 和 float)在内存中的存储方式。有两种主要的字节顺序:
大端序(Big Endian):最高有效字节(MSB)存放在最低地址。
小端序(Little Endian):最低有效字节(LSB)存放在最低地址。
不同的平台可能有不同的字节顺序,跨平台编程时要注意其中的区别。
这种大端小端模式表示的是字节之间的关系,一个字节内顺序还是从左往右数的。
不同数据类型的字节数
在C语言中,不同数据类型占用的字节数取决于具体的编译器和目标平台(如32位或64位系统)。然而,C标准规定了每种基本数据类型的最小大小,并且大多数现代编译器遵循这些规定。以下是一些常见数据类型的典型字节占用情况:
使用 sizeof 操作符来确定特定平台上某个数据类型的大小。
基本整数类型
char:1字节(8位)short int或short:至少2字节(通常是2字节)int:至少2字节(通常是4字节)long int或long:至少4字节(通常是4字节在32位系统上,8字节在64位系统上)long long int或long long:至少8字节
无符号整数类型
unsigned char:1字节unsigned short或unsigned short int:至少2字节unsigned int:至少2字节(通常是4字节)unsigned long或unsigned long int:至少4字节unsigned long long或unsigned long long int:至少8字节
浮点类型
-
float:4字节,单精度浮点数,提供大约7位有效数字。
根据IEEE 754标准,32位浮点数分为三部分:
符号位(S):第31位(最左边)
指数位(E):第30到第23位(接下来的8位)
尾数位(F):第22到第0位(剩下的23位)
解析时把对应的位数对应上去根据尾数乘以2^指数计算表示的十进制数值。 -
double:8字节,双精度浮点数,提供大约15位有效数字。 -
long double:至少10字节(具体取决于平台)扩展精度浮点数,具体实现可能不同,常见的有12字节或16字节。
可以用这个网站转换浮点数和16进制:https://www.toolhelper.cn/Digit/FractionConvert
指针类型
指针的大小取决于目标平台的架构:
- 32位系统:指针通常为4字节。
- 64位系统:指针通常为8字节。
其他类型
bool(C99引入):1字节,用于布尔值(true或false)。
注:结构体对齐:在结构体中,编译器可能会为了优化访问速度而进行成员对齐,这可能导致结构体的实际大小大于各成员大小之和。

浙公网安备 33010602011771号