09-c语言sizeof运算符
sizeof是C语言的编译时运算符,用于获取数据类型或对象的内存字节数(返回size_t类型),关键特性包括:数组名在sizeof中保留完整大小(不退化为指针)、结构体大小可能含填充字节、指针大小依赖系统位数(32位为4字节,64位为8字节);常用作计算数组元素个数(
sizeof(arr)/sizeof(arr[0])),但不可用于函数、位域或void类型。
基本概念
sizeof是C语言中的一个运算符,用于获取数据类型或对象在内存中占用的字节数- 作用:避免在程序中指定依赖于计算机的数据大小
- 是编译时计算,不会触发任何运行时操作(不会构造/析构对象、不会调用函数等)
- 返回值类型为
size_t,在头文件<stddef.h>中定义为无符号整数类型
语法形式
sizeof unary-expression // 对表达式求大小
sizeof (type-name) // 对类型名求大小
注意:
- 类型名必须用括号括起来(
sizeof(int)) - 表达式形式可以省略括号(
sizeof x) - 以下写法错误:
sizeof int,sizeof (x)(表达式形式可省略括号)
返回值类型
- 返回类型为
size_t(无符号整数) - 通常定义为
typedef unsigned int size_t;(64位系统可能是unsigned long) - 在64位系统中,
size_t是无符号长整型
常见类型大小(64位系统示例)
| 类型 | 大小(字节) | 说明 |
|---|---|---|
| char | 1 | C++标准保证 |
| int | 4 | 依赖于平台 |
| short | 2 | 依赖于平台 |
| long | 8 | 依赖于平台 |
| float | 4 | 依赖于平台 |
| double | 8 | 依赖于平台 |
| long double | 16 | 依赖于平台 |
| 指针 | 8 | 64位系统 |
| 数组 | 总字节数 | 如int a[10]为40字节 |
| 结构体 | 总字节数(含填充) | 依赖于对齐规则 |
常见用法
1. 计算数组元素个数
int arr[10];
size_t count = sizeof(arr) / sizeof(arr[0]); // 10
关键点:数组名在sizeof中不会退化为指针,保留"整个数组"身份
2. 用于内存分配
int *buffer = (int *)calloc(100, sizeof(int)); // 100个int的内存
3. 计算结构体大小
struct Example {
int a;
double b;
char c;
};
printf("Size of struct: %zu\n", sizeof(struct Example));
4. 指针大小
int *p;
printf("Size of pointer: %zu\n", sizeof(p)); // 64位系统为8
特殊情况与陷阱
1. 数组在不同上下文中的行为
| 上下文 | sizeof(arr) | 说明 |
|---|---|---|
| 在函数外 | 数组总大小 | 如int a[10]返回40 |
| 作为函数参数 | 指针大小 | void func(int arr[])中sizeof(arr)为4或8 |
| 数组名参与运算 | 指针大小 | sizeof(a+0)、sizeof(&a)为4或8 |
2. 结构体对齐
-
结构体大小可能包含填充字节
-
对齐规则:char(1)、short(2)、int(4)、double(8)
-
例如:
struct Example { char a; int b; // 会填充3字节 double c; }; // 实际大小可能为16(含填充)
3. 不能使用的场景
- 函数:
sizeof(func)错误 - 位域:
sizeof(struct S.f1)错误 - void类型:
sizeof(void)错误 - 未确定大小的数组作为结构体最后一个元素:返回没有该数组的结构体大小
4. 与strlen的区别
sizeof:计算对象在内存中占用的字节数(编译时确定)strlen:计算字符串实际长度(运行时确定,不包括终止符'\0')
实用示例
示例1:计算数组元素个数
int arr[10];
printf("%zu\n", sizeof(arr) / sizeof(arr[0])); // 输出10
示例2:结构体大小计算
struct Point {
int x;
int y;
double z;
};
printf("Size of struct: %zu\n", sizeof(struct Point));
// 可能为24(含填充)
示例3:指针与数组区别
int a[10];
int *p = a;
printf("%zu\n", sizeof(a)); // 40(数组总大小)
printf("%zu\n", sizeof(p)); // 8(指针大小)
printf("%zu\n", sizeof(a+0)); // 8(数组名退化为指针)
printf("%zu\n", sizeof(*a)); // 4(数组元素大小)
总结
sizeof是编译时计算,不触发运行时操作- 数组名在
sizeof中保留"整个数组"身份,不退化为指针 - 结构体大小包含填充字节,与成员大小之和可能不一致
- 指针大小依赖于系统位数(32位为4,64位为8)
- 不能用于函数、位域、void类型、动态分配的数组
- 常用表达式:
sizeof(array)/sizeof(array[0])计算数组元素个数
掌握sizeof运算符,能帮助你在内存管理、底层编程和跨平台开发中更加得心应手。
- 感谢你赐予我前进的力量
赞赏者名单
因为你们的支持让我意识到写文章的价值🙏
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 软件从业者Hort
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果

