整型(Integer Types)全面解析

一、整型分类体系

1. 基本整型(标准规定的最小尺寸)
类型 最小位数 典型尺寸(64位系统) 取值范围(典型)
char 8位 8位(1字节) -128~127 或 0~255
short 16位 16位(2字节) -2^15 ~ 2^15-1
int 16位 32位(4字节) -2^31 ~ 2^31-1
long 32位 32或64位 -2^31 ~ 2^31-1 或 -2^63 ~ 2^63-1
long long 64位 64位(8字节) -2^63 ~ 2^63-1
2. 符号修饰符
  • signed:有符号(默认,可省略)
  • unsigned:无符号(仅非负值)
unsigned int positive = 42;   // 0~4.2e9
signed char temperature = -5; // -128~127
3. 尺寸精确类型(C++11)
#include <cstdint>
int8_t  small;    // 精确8位
int32_t medium;   // 精确32位
uint64_t large;   // 无符号64位

二、关键特性深度解析

1. 字面量表示
int decimal = 42;          // 十进制
int octal = 052;           // 八进制(前导0)
int hex = 0x2A;            // 十六进制(0x前缀)
unsigned long long big = 10'000'000; // C++14数字分隔符
2. 类型转换规则
  • 整数提升:小类型运算前自动提升为int

    short a = 10;
    short b = 20;
    auto c = a + b; // c是int类型,非short!
    
  • 符号转换:混合运算时自动转换

    unsigned u = 10;
    int i = -5;
    auto r = u + i; // 可能溢出!r为unsigned
    
3. 溢出处理(未定义行为)
int max = INT_MAX; // 2147483647
max++;             // 未定义行为!可能变为-2147483648

三、典型陷阱与解决方案

1. 符号比较陷阱
unsigned int u = 10;
int i = -5;

// 错误:负数转为大正数
if (i < u) { 
    // 实际:-5 → 4294967291 > 10
    // 此代码块不会执行!
}

解决方案

// 正确比较方式
if (i < 0 || static_cast<unsigned>(i) < u) {
    // 安全比较逻辑
}
2. 类型推导陷阱
auto size = vector.size(); // size_t(无符号)
for (int i = 0; i < size - 1; ++i) {
    // 当size=0时:size-1=4294967295 → 死循环!
}

解决方案

// 正确方式1:统一使用size_t
for (size_t i = 0; i < size; ++i)

// 正确方式2:C++20范围循环
for (auto& item : vector)
3. 移位操作陷阱
int a = 1 << 31;    // 有符号左移31位 → 未定义行为
uint32_t b = 1 << 31; // 无符号安全移位

解决方案

// 安全移位:使用无符号类型
auto flags = uint32_t{1} << 31;

四、最佳实践指南

  1. 精确类型选择原则

    // 优先选择
    uint8_t for_buffer[1024];  // 内存敏感场景
    int32_t for_counter;       // 通用计数器
    size_t for_index;          // 容器索引/大小
    
  2. 避免隐式转换

    // 使用显式转换
    auto value = static_cast<uint16_t>(large_num);
    
  3. 边界检查工具

    #include <limits>
    if (input > std::numeric_limits<int16_t>::max()) {
        throw std::overflow_error("Input too large");
    }
    
  4. C++20安全整数库

    #include <utility>
    auto [result, overflow] = std::add_overflow(a, b);
    if (overflow) { /* 处理溢出 */ }
    

五、平台移植性策略

  1. 尺寸相关代码

    // 避免直接假设尺寸
    #if INTPTR_MAX == INT64_MAX
        // 64位平台代码
    #elif INTPTR_MAX == INT32_MAX
        // 32位平台代码
    #endif
    
  2. 字节序处理

    #include <bit>
    if constexpr (std::endian::native == std::endian::little) {
        // 小端序处理
    }
    
  3. 类型别名技巧

    using FileSize = uint64_t; // 跨平台统一类型
    

终极建议:

  1. 索引/大小 始终用size_t
  2. 位操作 始终用无符号类型
  3. 网络传输 使用固定尺寸类型(如uint32_t
  4. 财务计算 避免整型(用decimal库)
  5. 关键计算 必须添加溢出检查
posted on 2025-06-27 17:11  青·丝  阅读(61)  评论(0)    收藏  举报