别再猜了C/C里int、long、long long到底占几个字节一个程序帮你全看清刚接触C/C时数据类型的内存占用总是让人头疼——教科书上说int通常占4字节但为什么同事的代码里突然冒出8字节的long跨平台移植时更是一团糟。与其死记硬背各种平台的规则不如自己动手验证。本文将带你用几行代码揭开数据类型的真实面纱同时解释不同编译器和操作系统下的差异。1. 为什么需要验证数据类型大小教科书和网络资料中关于基本类型大小的描述往往附带通常、一般这样的模糊限定词。这是因为C/C标准故意没有严格规定具体字节数只做了相对约束short int≤int≤long int≤long long intchar≥ 8位sizeof(char) 1字节是C/C中内存计量的最小单位这种灵活性带来了历史兼容性但也导致现实中的混乱。例如在常见的三种现代系统中类型Windows x64Linux x64macOS x64int444long488long long888注意上表仅展示常见情况实际结果可能因编译器版本而异2. 构建验证程序下面这个不到30行的程序可以输出所有关键整数类型的大小#include stdio.h #include stdint.h int main() { printf( 类型大小检测 \n); printf(char: %zu\n, sizeof(char)); printf(short: %zu\n, sizeof(short)); printf(int: %zu\n, sizeof(int)); printf(long: %zu\n, sizeof(long)); printf(long long: %zu\n, sizeof(long long)); printf(指针: %zu\n, sizeof(void*)); printf(size_t: %zu\n, sizeof(size_t)); printf(uint64_t: %zu\n, sizeof(uint64_t)); printf(int64_t: %zu\n, sizeof(int64_t)); return 0; }关键点说明%zu是size_t类型的专用格式说明符sizeof是编译时运算符返回类型或对象占用的字节数stdint.h提供了固定宽度类型如uint64_t3. 多平台实测对比3.1 Windows平台MSVC编译器在Visual Studio 2022默认配置下运行结果 类型大小检测 char: 1 short: 2 int: 4 long: 4 long long: 8 指针: 8 size_t: 8 uint64_t: 8 int64_t: 8Windows的独特之处在于保持long为4字节历史兼容性LLP64数据模型Long和Pointer为64位3.2 Linux平台GCC编译器Ubuntu 22.04下gcc 11.3.0的典型输出 类型大小检测 char: 1 short: 2 int: 4 long: 8 long long: 8 指针: 8 size_t: 8 uint64_t: 8 int64_t: 8Linux采用LP64模型long升级为8字节与Unix传统保持一致3.3 macOS平台Clang编译器MacBook Pro M1上的运行结果 类型大小检测 char: 1 short: 2 int: 4 long: 8 long long: 8 指针: 8 size_t: 8 uint64_t: 8 int64_t: 8macOS虽然使用不同编译器但数据模型与Linux一致基于Unix的LP64传统ARM架构不影响基本类型大小4. 工程实践建议根据实测结果给出以下实用建议需要固定大小时使用stdint.h中的明确类型uint8_t // 无符号8位 int32_t // 有符号32位 uint64_t // 无符号64位指针和大小表示表示内存大小时总是用size_t指针运算时使用ptrdiff_t跨平台代码防护#if INTPTR_MAX INT64_MAX // 64位环境代码 #elif INTPTR_MAX INT32_MAX // 32位环境代码 #else #error Unknown pointer size #endif避免的陷阱不要假设long是64位Windows例外不要用int存储指针用uintptr_t序列化时不要直接使用基本类型5. 深入理解sizeof这个看似简单的运算符有几个关键特性编译时求值不会真正执行代码返回类型为size_t足够大的无符号整型对数组返回总字节数对指针返回指针大小不是指向对象的大小示例int arr[10]; printf(%zu\n, sizeof(arr)); // 输出40假设int为4字节 int *p arr; printf(%zu\n, sizeof(p)); // 输出864位系统6. 扩展验证结构体对齐数据类型大小还会影响结构体布局。添加以下测试代码struct Test { char c; int i; long l; }; printf(结构体大小: %zu\n, sizeof(struct Test)); printf(成员偏移c%zu, i%zu, l%zu\n, offsetof(struct Test, c), offsetof(struct Test, i), offsetof(struct Test, l));典型输出Linux x64结构体大小: 16 成员偏移c0, i4, l8这说明编译器在char c后插入了3字节填充以满足int i的4字节对齐要求。