在无<limits.h>或<values.h>的系统中获取SHRT_MAX的方法解析
拆解推导SHRT_MAX的代码逻辑
嘿,我来一步步给你掰明白这段代码到底在干啥,全程用大白话,保证你能懂!
首先先把这段代码完整放出来,方便对照:
const CHAR_BIT= 8; #define BITS(type) (CHAR_BIT*(int)sizeof(type)) #define HIBIT(type) ((type)(1<< (BITS(type)-1))) #define TYPE_MAX(type) ((type)~HIBIT(type)); const SHRT_MAX= TYPE_MAX(short);
接下来逐行拆解:
1. const CHAR_BIT= 8;
这行很简单,定义了一个常量CHAR_BIT,值是8——它代表一个字节占多少个二进制位。咱们平时用的电脑里,字节基本都是8位的,所以这里直接硬编码成8了(不过要注意,有些特殊系统可能不是8位,但绝大多数场景没问题)。
2. #define BITS(type) (CHAR_BIT*(int)sizeof(type))
这是个宏,用来计算某个数据类型type总共占多少个二进制位。
sizeof(type):会返回这个类型占多少个字节,比如short通常是2字节,那sizeof(short)就是2。- 乘以
CHAR_BIT(8):2*8=16,就得到short总共占16位。 - 加
(int):是把sizeof返回的size_t类型转成int,避免后续计算出现类型不匹配的问题。 - 括号全加上:是为了防止宏展开后被其他运算符的优先级坑到,比如如果不加括号,遇到复杂表达式可能会算错。
3. #define HIBIT(type) ((type)(1<< (BITS(type)-1)))
这个宏的作用是拿到该类型的最高位(符号位)为1,其他位都是0的数值。
- 先算
BITS(type)-1:比如short是16位,那就是16-1=15。 1 << 15:把数字1的二进制向左移15位,得到的二进制是10000000 00000000(16位),这个数在int里是32768,但咱们要的是short类型的数值,所以强制转成(type)也就是short。- 转成
short后,因为有符号整数用补码存储,最高位是符号位,1代表负数,所以这个值其实是-32768(short的最小值)。
4. #define TYPE_MAX(type) ((type)~HIBIT(type))
这一步就是推导该类型的最大值了,核心是按位取反操作~:
HIBIT(type)得到的是最高位为1、其他为0的数,比如short的就是10000000 00000000。- 按位取反后,最高位的1变成0,其他所有0都变成1,也就是
01111111 11111111,这个二进制数对应的十进制就是32767——正好是short类型能存的最大正数。 - 同样强制转成
(type),确保类型正确。
5. const SHRT_MAX= TYPE_MAX(short);
最后一步很直白,调用TYPE_MAX宏传入short类型,把得到的最大值赋值给SHRT_MAX常量,这就得到了咱们要的短整型最大值。
额外提醒
实际开发中,咱们完全不用自己写这段代码,直接包含<climits>头文件就能用系统定义好的SHRT_MAX了——这段代码主要是用来演示“如何从底层逻辑推导有符号整数的最大值”,帮你理解二进制和补码的原理。
内容的提问来源于stack exchange,提问作者Ashutosh Tiwari
相关产品推荐
相关产品推荐

