Appearance
C语言中的数据类型与转换
考情分析
整数类型转换是选择题高频考点(2011、2016、2019、2021、2024),int/float 精度问题也多次出现(2010、2017)。核心在于理解"位模式不变,解释方式变"和"扩展/截断"两个原则。
无符号整数与有符号整数
| 类型 | 编码方式 | 8位范围 |
|---|---|---|
| 无符号整数 | 纯二进制,所有位表示数值 | |
| 有符号整数 | 补码,最高位为符号位 |
同样的 8 位二进制 10000000:
- 作为无符号数解释:128
- 作为有符号数(补码)解释:
现代计算机统一用补码表示有符号整数,因为:零的表示唯一、加减法统一为加法、比原码多表示一个最小负数。
C 语言整数类型
| 类型 | 典型位宽 | 有符号范围 | 无符号范围 |
|---|---|---|---|
| char | 8 | ||
| short | 16 | ||
| int | 32 | ||
| long | 32/64 | 取决于平台 | 取决于平台 |
未声明 unsigned 则默认为有符号类型。
类型转换的三种情形
1. 相同字长:位模式不变,解释方式变
c
short x = -4321;
unsigned short y = (unsigned short)x;
// x = -4321, y = 61215x 和 y 的二进制完全相同(0xEF1F),但 x 按补码解释为
关键规律:
- 若
: - 若
:
所以 (unsigned short)(-1) =
2. 短类型 → 长类型:位扩展
| 源类型 | 扩展方式 | 规则 |
|---|---|---|
| 有符号数 | 符号扩展 | 高位填充符号位 |
| 无符号数 | 零扩展 | 高位填充 0 |
c
short x = -4321; // 0xEF1F
int y = x; // 符号扩展 → 0xFFFFEF1F,值仍为 -4321
unsigned short u = 61215; // 0xEF1F
unsigned int v = u; // 零扩展 → 0x0000EF1F,值仍为 61215符号扩展保持数值不变(补码的性质),零扩展保持无符号值不变。
3. 长类型 → 短类型:截断
直接丢弃高位,仅保留低位。截断可能导致数值完全改变。
c
int x = 165537; // 0x000286A1
short y = (short)x; // 截断为 0x86A1,解释为 -31071int 与 float/double 的转换
| 转换方向 | 可能发生的问题 |
|---|---|
| int → float | 不溢出,但可能精度丢失(int 32 位有效位 > float 24 位尾数) |
| int → double | 安全(double 52 位尾数,足以精确表示 32 位 int) |
| float → double | 安全(精度和范围都扩大) |
| double → float | 可能溢出(超出 float 范围)或精度丢失 |
| float/double → int | 小数部分截断(向零取整),可能溢出 |
例:int → float 精度丢失
c
int n = 0x7FFFFFFF; // 2147483647,二进制有效位 31 位
float f = (float)n; // float 尾数只有 23+1=24 位,需舍入
int m = (int)f; // m 可能不等于 n原因:
隐式类型提升顺序:
混合运算时,较低类型自动转换为较高类型。
考点清单
- 相同字长转换:位模式不变,仅改变解释方式
- 短→长:有符号做符号扩展,无符号做零扩展
- 长→短:截断高位,可能导致值完全改变
(unsigned)(-1)得到该类型的最大值(全 1)- int → float:不溢出但可能丢精度(24 位尾数 < 32 位)
- int → double:安全(52 位尾数足够)
- float/double → int:截断小数,可能溢出