这是一个非常基础且重要的知识点,理解它对于编写可移植、健壮的 C 代码至关重要。

一句话总结:int 和 long 都是用来表示整数的,但它们的关键区别在于“大小”(即所占内存字节数)和“范围”(即可表示的数值大小),而这个大小和范围在不同的操作系统和编译器上可能是不同的。
核心区别:大小和范围
| 特性 | int |
long |
|---|---|---|
| 中文含义 | 整型 | 长整型 |
| 设计初衷 | 作为系统“最自然”的整数类型,通常与CPU寄存器大小匹配。 | 用于表示比 int 更大的整数,确保有足够的范围。 |
| 大小(字节) | 不固定,通常是 2 或 4 字节。 | 不固定,通常是 4 或 8 字节。 |
| 范围 | 取决于其大小,4字节 int 范围是 -2,147,483,648 到 2,147,483,647。 |
比 int 更大或相等,4字节 long 范围与 int 相同;8字节 long 范围则大得多。 |
详细解释
A. int (整型)
int 是 C 语言中最基本、最常用的整数类型。
- 大小不固定:
int的大小取决于编译器和目标平台。- 在过去(16位系统,如 DOS),
int通常是 2字节 (16位)。 - 在现在绝大多数的 32位 和 64位 系统(如 Windows, Linux, macOS)上,
int都是 4字节 (32位)。
- 在过去(16位系统,如 DOS),
- 为什么大小不固定? 这是为了让 C 语言能更好地与底层硬件结合,编译器会选择与 CPU 架构最匹配的整数类型作为
int,以获得最佳性能,在 32 位 CPU 上,一次处理 32 位(4字节)的数据是最快的。
B. long (长整型)
long 的设计初衷就是提供一个比 int 更大的整数类型,以确保能存储更大的数值。
- 大小同样不固定:
long的大小在不同系统上差异更大。- 在 32位系统上:
long通常是 4字节 (32位),和int一样大。 - 在 64位系统上:
long通常是 8字节 (64位),这比int(4字节) 大得多。
- 在 32位系统上:
- 一个常见的误区:很多人认为
long一定比int大,这在 64 位系统上是正确的,但在 32 位系统上,它们的大小是相等的,这是导致代码在不同平台上出现问题的常见原因。
标准与保证
C 标准只对 int、short 和 long 的大小关系做了最低限度的保证:

sizeof(short) <= sizeof(int) <= sizeof(long)
这意味着:
short的大小不会超过int。int的大小不会超过long。
但没有保证 int 一定小于 long,也没有规定它们具体是多少字节。
代码示例与陷阱
这个例子非常经典,能清晰地展示问题所在。
#include <stdio.h>
#include <limits.h> // 包含各种整数类型的限制信息
int main() {
// 使用 sizeof 操作符查看类型大小
printf("Size of int: %zu bytes\n", sizeof(int));
printf("Size of long: %zu bytes\n", sizeof(long));
// 使用 limits.h 中的宏定义查看范围
printf("Range of int: %d to %d\n", INT_MIN, INT_MAX);
printf("Range of long: %ld to %ld\n", LONG_MIN, LONG_MAX);
// --- 一个常见的陷阱 ---
long a = 2147483648; // 这个数字已经超过了 4字节 int 的最大值 (2147483647)
// 在 32 位系统上,long 和 int 都是 4 字节,这行代码可能会产生警告或错误。
// 在 64 位系统上,long 是 8 字节,这没有问题。
// 为了写出可移植的代码,应该使用固定大小的类型
printf("\n--- Portable Solution ---\n");
printf("Size of int32_t: %zu bytes\n", sizeof(int32_t));
printf("Size of int64_t: %zu bytes\n", sizeof(int64_t));
printf("Range of int32_t: %d to %d\n", INT32_MIN, INT32_MAX);
printf("Range of int64_t: %lld to %lld\n", INT64_MIN, INT64_MAX);
return 0;
}
运行结果分析:
-
在 32位 Linux/Windows 系统上编译运行:
Size of int: 4 bytes Size of long: 4 bytes Range of int: -2147483648 to 2147483647 Range of long: -2147483648 to 2147483647你会发现
int和long的大小和范围完全一样。 -
在 64位 Linux/Windows/macOS 系统上编译运行:
Size of int: 4 bytes Size of long: 8 bytes Range of int: -2147483648 to 2147483647 Range of long: -9223372036854775808 to 9223372036854775807这里
long明显比int大得多。
如何选择?最佳实践
了解了它们的区别后,我们应该如何在代码中做出选择?
需要精确控制整数大小(推荐)
当你需要一个特定大小的整数时(网络协议、文件格式、硬件寄存器操作),永远不要依赖 int 或 long。
你应该使用 C99 标准引入的 <stdint.h> 头文件中定义的固定宽度整数类型。
| 类型 | 描述 | 大小 |
|---|---|---|
int8_t |
8位有符号整数 | 1 字节 |
int16_t |
16位有符号整数 | 2 字节 |
int32_t |
32位有符号整数 | 4 字节 |
int64_t |
64位有符号整数 | 8 字节 |
uint32_t |
32位无符号整数 | 4 字节 |
示例:
#include <stdint.h> // 如果你需要一个 32 位的整数,无论在什么平台上 int32_t network_packet_id = 0x12345678;
用于通用计算、循环计数器
在不需要精确大小,只需要一个普通整数的场景下(for 循环、数组索引),使用 int 通常是安全的。
int i;
for (i = 0; i < 1000; i++) {
// ...
}
需要处理非常大的整数
如果你需要存储的整数可能超过 int32_t 的范围(大约 21 亿),那么你应该使用 int64_t。
什么时候使用 long?
在现代 C 开发中,直接使用 long 的情况越来越少,主要可能出现在以下场景:
- 与特定平台的 API 交互:某些操作系统或库的函数可能明确要求使用
long类型作为参数。 - 处理文件大小:在 POSIX 标准中,
off_t类型(用于文件大小和偏移量)在某些实现上可能与long相同。 - 遗留代码维护:维护旧代码时,需要遵循原有的风格。
总结表格
| 特性 | int |
long |
int32_t / int64_t (推荐) |
|---|---|---|---|
| 大小 | 不固定 (通常是 4 字节) | 不固定 (32位系统4字节, 64位系统8字节) | 固定 (如 int32_t 永远是 4 字节) |
| 可移植性 | 差,大小和范围依赖平台。 | 差,大小和范围依赖平台。 | 极佳,行为在所有符合标准的编译器上完全一致。 |
| 适用场景 | 通用计算、循环计数器。 | 平台 API 交互、遗留代码。 | 网络、文件格式、跨平台开发、任何需要精确大小的场景。 |
| 使用建议 | 可以用于通用场景。 | 谨慎使用,优先考虑固定宽度类型。 | 首选,尤其是在编写需要长期维护或跨平台的代码时。 |
最终建议:
除非有特殊原因(如调用特定 API),否则在编写现代、健壮、可移植的 C 代码时,应优先使用
<stdint.h>中定义的固定宽度整数类型(如int32_t,int64_t),而不是依赖int和long的大小。
