不用sizeof计算数据类型大小
2026/9/1大约 3 分钟
不使用 sizeof 计算数据类型大小
sizeof 能直接得到类型或变量占用的字节数。
不用 sizeof,可以利用:
#define mysizeof(value) \
((char *)(&value + 1) - (char *)(&value))一、核心原理
假设:
int a;看:
& a是 int *,指向 a。
而:
&a + 1不是加 1 个字节,而是向后移动 1 个 **int。
如果 int 是 4 字节:
&a → 0x1000
&a + 1 → 0x1004所以两个地址相差:
4 字节二、为什么要转成 char *?
因为:
&a + 1 - &a得到的是元素个数,不是字节数。
假设:
int a;那么 &a 的类型是:
int *对于 int * 来说:
&a + 1表示向后移动一个 int,而不是移动 1 个字节。
如果 int 占 4 个字节:
&a → 1000
&a + 1 → 1004但是指针相减时:
&a + 1 - &a结果不是 4,而是:
1因为它表示两个 int * 之间相隔了几个 int 元素。
为什么不能转成 int *?
如果写成:
(int *)(&a + 1) - (int *)(&a)两个指针仍然是 int *。
它们之间相差一个 int,所以结果仍然是:
1并没有得到字节数。
为什么使用 char *?
把地址转换成 char *:
(char *)(&a + 1)
(char *)(&a)此时,指针相减会按照 char 元素计算。
而 char 在 C 语言中规定占用 1 个字节,所以:
每相差 1 个 char
= 相差 1 个字节如果 int 占 4 个字节:
(char *)(&a) → 1000
(char *)(&a + 1) → 1004相减结果就是:
1004 - 1000 = 4因此:
(char *)(&a + 1) - (char *)(&a)得到的就是 a 占用的字节数。
char、int 和字节的关系
这里的 char 不是因为它“比较小”才使用,而是因为:
C 语言规定 ***
sizeof(char)*** 永远等于 1。
所以:
char * 指针相减
→ 得到相差多少个 char
→ 得到相差多少个字节而 int 的大小并不固定,可能是 2、4 或其他字节数。
如果使用 int *:
int * 指针相减
→ 得到相差多少个 int得到的只是元素个数,不是字节数。
所以这里必须使用 char *,因为我们需要让地址差按照最小的字节单位来计算。
原类型指针跨过一个完整对象
↓
转换成 char *
↓
按照 1 字节为单位计算地址差
↓
得到对象占用的字节数三、完整例子
#include <stdio.h>
#define mysizeof(value) \
((char *)(&value + 1) - (char *)(&value))
int main(void)
{
int a;
char b;
double c;
printf("%ld\n", mysizeof(a));
printf("%ld\n", mysizeof(b));
printf("%ld\n", mysizeof(c));
return 0;
}典型结果:
4
1
8四、一句话理解
&value
↓
指向当前对象
&value + 1
↓
跨过整个对象
两个地址相减
↓
得到对象占用的字节数核心:
先用原类型指针跨过一个完整对象,再转换成 ***
char \**** 按字节计算地址差。
注意:这个宏针对的是变量/对象,不是直接计算裸类型名;实际工程中当然优先使用标准的 sizeof。

