news 2026/6/8 12:12:26

别再猜了!C/C++里int、long、long long到底占几个字节?一个程序帮你全看清

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
别再猜了!C/C++里int、long、long long到底占几个字节?一个程序帮你全看清

别再猜了!C/C++里int、long、long long到底占几个字节?一个程序帮你全看清

刚接触C/C++时,数据类型的内存占用总是让人头疼——教科书上说int通常占4字节,但为什么同事的代码里突然冒出8字节的long?跨平台移植时更是一团糟。与其死记硬背各种平台的规则,不如自己动手验证。本文将带你用几行代码揭开数据类型的真实面纱,同时解释不同编译器和操作系统下的差异。

1. 为什么需要验证数据类型大小?

教科书和网络资料中关于基本类型大小的描述往往附带"通常"、"一般"这样的模糊限定词。这是因为C/C++标准故意没有严格规定具体字节数,只做了相对约束:

  • short intintlong intlong long int
  • char≥ 8位
  • sizeof(char)== 1(字节是C/C++中内存计量的最小单位)

这种灵活性带来了历史兼容性,但也导致现实中的混乱。例如在常见的三种现代系统中:

类型Windows x64Linux x64macOS x64
int444
long488
long 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; }

关键点说明:

  • %zusize_t类型的专用格式说明符
  • sizeof是编译时运算符,返回类型或对象占用的字节数
  • stdint.h提供了固定宽度类型如uint64_t

3. 多平台实测对比

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: 8

Windows的独特之处在于:

  • 保持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: 8

Linux采用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: 8

macOS虽然使用不同编译器,但数据模型与Linux一致:

  • 基于Unix的LP64传统
  • ARM架构不影响基本类型大小

4. 工程实践建议

根据实测结果,给出以下实用建议:

  1. 需要固定大小时

    • 使用<stdint.h>中的明确类型:
      uint8_t // 无符号8位 int32_t // 有符号32位 uint64_t // 无符号64位
  2. 指针和大小表示

    • 表示内存大小时总是用size_t
    • 指针运算时使用ptrdiff_t
  3. 跨平台代码防护

    #if INTPTR_MAX == INT64_MAX // 64位环境代码 #elif INTPTR_MAX == INT32_MAX // 32位环境代码 #else #error "Unknown pointer size" #endif
  4. 避免的陷阱

    • 不要假设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)); // 输出8(64位系统)

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 成员偏移:c=0, i=4, l=8

这说明编译器在char c后插入了3字节填充以满足int i的4字节对齐要求。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/8 12:05:03

汽车传感器自检实战:基于DSI3总线的FXLS9xxxx加速度计完整流程

1. 项目概述与核心价值在汽车电子、工业控制这些对功能安全要求极高的领域&#xff0c;传感器数据的可靠性不是“加分项”&#xff0c;而是“生命线”。想象一下&#xff0c;一辆高速行驶的汽车&#xff0c;其气囊控制器依赖的加速度传感器如果发生漂移或故障而未被及时察觉&am…

作者头像 李华
网站建设 2026/6/8 11:59:54

Plain Craft Launcher 2:终极Minecraft启动器完整指南

Plain Craft Launcher 2&#xff1a;终极Minecraft启动器完整指南 【免费下载链接】PCL Minecraft 启动器 Plain Craft Launcher&#xff08;PCL&#xff09;。 项目地址: https://gitcode.com/gh_mirrors/pc/PCL Plain Craft Launcher 2&#xff08;简称PCL2&#xff0…

作者头像 李华
网站建设 2026/6/8 11:58:32

如何高效使用DamaiHelper大麦抢票脚本:5个专业技巧告别抢票烦恼

如何高效使用DamaiHelper大麦抢票脚本&#xff1a;5个专业技巧告别抢票烦恼 【免费下载链接】DamaiHelper 大麦网演唱会演出抢票脚本。 项目地址: https://gitcode.com/gh_mirrors/dama/DamaiHelper 还在为抢不到心仪的演唱会门票而烦恼吗&#xff1f;DamaiHelper大麦抢…

作者头像 李华