C標準只規定整型最小範圍(如int至少16位),具體寬度由實現定義。直接硬編碼2147483647會導致移植災難。<limits.h>提供編譯期常量,保證代碼在16/32/64位、大小端、補碼/反碼/符號幅度機器上正確運行。
| 宏名 | 含義 | 典型值 | 十六進制 |
|---|---|---|---|
CHAR_BIT | 位元組位數 | 8 | 0x8 |
SCHAR_MIN | signed char最小值 | -128 | 0x80 |
SCHAR_MAX | signed char最大值 | 127 | 0x7F |
UCHAR_MAX | unsigned char最大值 | 255 | 0xFF |
CHAR_MIN | char最小值 | -128 (或0) | - |
CHAR_MAX | char最大值 | 127 (或255) | - |
MB_LEN_MAX | 多字節字符最大長度 | 2 (或更大) | - |
SHRT_MIN | short最小值 | -32768 | 0x8000 |
SHRT_MAX | short最大值 | 32767 | 0x7FFF |
USHRT_MAX | unsigned short最大值 | 65535 | 0xFFFF |
INT_MIN | int最小值 | -2147483648 | 0x80000000 |
INT_MAX | int最大值 | 2147483647 | 0x7FFFFFFF |
UINT_MAX | unsigned int最大值 | 4294967295 | 0xFFFFFFFF |
LONG_MIN | long最小值 | -2147483648 (32位) / -9.22e18 (64位) | - |
LONG_MAX | long最大值 | 2147483647 (32位) / 9.22e18 (64位) | - |
ULONG_MAX | unsigned long最大值 | 4294967295 (32位) / 1.84e19 (64位) | - |
LLONG_MIN | long long最小值 (C99) | -9223372036854775808 | 0x8000000000000000 |
LLONG_MAX | long long最大值 (C99) | 9223372036854775807 | 0x7FFFFFFFFFFFFFFF |
ULLONG_MAX | unsigned long long最大值 (C99) | 18446744073709551615 | 0xFFFFFFFFFFFFFFFF |
// 錯誤:INT_MAX + 1 觸發UB
int x = INT_MAX + 1;
// 正確:用無符號或檢查
if (a > INT_MAX - b) handle_overflow();
else int c = a + b;
// 或用無符號運算(定義行為:模2^N環)
unsigned int ua = a, ub = b;
unsigned int uc = ua + ub; // 永不UB
// 錯誤:abs(INT_MAX) 可能溢出(|INT_MIN| > INT_MAX)
int y = abs(x);
// 正確:轉無符號或手動處理
unsigned int uy = (x < 0) ? -(unsigned int)x : x; // 安全
// 或 C23: std::abs(int) 返回長類型
// 未定義:移位量 >= 位寬 或 左移負數/溢出
int z = 1 << 32; // UB if int是32位
// 安全:用無符號且檢查
unsigned int mask = (n < 32) ? (1u << n) : 0;
printf("INT_MAX = %d\n", INT_MAX); // %d/%i
printf("UINT_MAX = %u\n", UINT_MAX); // %u
printf("LONG_MAX = %ld\n", LONG_MAX); // %ld
printf("LLONG_MAX = %lld\n", LLONG_MAX); // %lld
printf("PTRDIFF_MAX = %td\n", PTRDIFF_MAX); // %td (C99)
printf("SIZE_MAX = %zu\n", SIZE_MAX); // %zu (C99)
// C11 Static Assert
_Static_assert(INT_MAX >= 2147483647, "int至少32位");
_Static_assert(CHAR_BIT == 8, "假設位元組8位");
// 檢查類型寬度
#if UINT_MAX == 0xFFFFFFFF
typedef uint32_t my_uint32;
#elif UINT_MAX == 0xFFFFFFFFFFFFFFFF
typedef uint64_t my_uint32; // 錯誤示例
#endif
<stdint.h> 新增 INT8_MAX, UINT_LEAST16_MAX, INT_FAST32_MAX 等,配合 intN_t, uint_leastN_t, int_fastN_t 類型,提供更精確控制。
limits.h 是 C 程序員的「護身符」。牢記:永不硬編碼邊界值、有符號溢出是UB、優先用無符號做位運算、格式化字符串匹配類型。配合 stdint.h 固定寬度類型與 inttypes.h 格式化宏,編寫真正可移植、健壯的系統級代碼。