long 类型
long(或 long int)是 C 语言中比 int 更大的整数类型,标准保证至少 32 位。当 int 的 32 位范围不足以容纳数据时使用。但 long 的大小因平台而异,是 C 语言可移植性的一个痛点。
基本用法
long population = 7800000000L; /* 世界人口约 78 亿 */
printf("sizeof(long) = %zu\n", sizeof(long));
/* Linux 64 位:8;Windows 64 位:4;Linux 32 位:4 */
long 的取值范围:
#include <limits.h>
printf("LONG_MIN = %ld\n", LONG_MIN);
printf("LONG_MAX = %ld\n", LONG_MAX);
/* 32 位 long:-2147483648 到 2147483647 */
/* 64 位 long:-9223372036854775808 到 9223372036854775807 */
平台差异
long 的大小不一致是 C 语言可移植性的一个痛点:
| 平台 | sizeof(long) |
|---|---|
| 32 位 Linux | 4 字节 |
| 64 位 Linux | 8 字节 |
| 64 位 Windows (LLP64) | 4 字节 |
如果代码在 Windows 和 Linux 之间移植,依赖 long 为 64 位的假设会出错。
整数常量后缀
long 常量使用 L 后缀(建议大写,避免小写 l 与数字 1 混淆):
long val = 1000000L;
long big = 3000000000L; /* 超出 int 范围时必须用 L 后缀 */
unsigned long uval = 42UL;
格式化输入输出
| 类型 | printf | scanf |
|---|---|---|
long | %ld | %ld |
unsigned long | %lu | %lu |
long l = 1000000L;
printf("long: %ld\n", l);
scanf("%ld", &l);
C99 的 <inttypes.h> 提供了跨平台的格式宏,在类型大小不确定时更安全:
#include <inttypes.h>
int64_t value = 1234567890123L;
printf("Value: %" PRId64 "\n", value); /* 展开为平台正确的格式 */
无符号版本
unsigned long 只表示非负数,正数范围扩大一倍:
unsigned long huge = 4000000000UL;
printf("ULONG_MAX = %lu\n", ULONG_MAX);
无符号类型常用于:
- 位运算和标志掩码
- 内存大小和数组索引(
sizeof返回size_t,通常基于unsigned long) - 哈希值、校验和等不可能为负的数值
跨平台建议
如果代码需要在不同平台间移植,<stdint.h> 的定宽类型是最佳选择:
#include <stdint.h>
int32_t exact32; /* 保证 32 位有符号 */
int64_t exact64; /* 保证 64 位有符号 */
这些类型在所有 C99 兼容平台上大小一致,消除了 int、long 大小不确定的问题。如果需要保证 64 位,应使用 int64_t 而非 long。
常见错误
格式说明符不匹配:
long l = 1000000000L;
printf("%d\n", l); /* 错误:%d 对应 int,l 是 long */
printf("%ld\n", l); /* 正确 */
常量后缀遗漏:
long big = 3000000000; /* 警告:在 32 位 int 平台上可能溢出 */
long correct = 3000000000L; /* 正确:明确指定为 long 常量 */