You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言简易sizeof宏实现原理与char*类型转换作用解析

原问题背景

我在学习C语言时遇到了一个简化版sizeof实现,代码如下:

#include <stdio.h> 

#define mySizeof(type) ((char*)(&type + 1) - (char*)(&type))

int main() {
    char x;
    int y;
    double z;
    printf("mySizeof(char)   is : %ld\n", mySizeof(x));
    printf("mySizeof(int)    is : %ld\n", mySizeof(y));
    printf("mySizeof(double) is : %ld\n", mySizeof(z));
}

注:本次不讨论该实现的兼容性问题,仅解释其工作逻辑,该实现对示例中三类基础变量可以正常运行。

核心疑问:

  • 上述mySizeof宏的运行原理是什么?
  • 宏中char*强制类型转换的作用是什么?
  • 为什么两个实际地址差4字节的int*指针直接相减结果为1,和实际字节数不一致?

对应的验证测试代码:

#include <stdio.h>

#define Address(x) (&x)
#define NextAddress(x) (&x + 1)

int main() {
    int n = 1;
    printf("address is : %lld\n", Address(n));
    printf("next address is : %lld\n", NextAddress(n));
    printf("size is %lld\n", NextAddress(n) - Address(n));
    return 0;
}

测试输出:

address is : 140721498241924
next address is : 140721498241928
size is 1

原理解释

1. C语言指针运算的核心规则

C语言中指针的加减运算不是以字节为单位,而是以指针指向的类型的大小为单位。
举个例子:

  • 对于int* p,p+1不是地址值加1,而是地址值加sizeof(int),也就是指向内存中下一个相邻的int类型变量的位置。
  • 两个同类型指针相减,得到的结果也不是地址的字节差值,而是两个指针之间间隔的对应类型元素的个数。

这就是测试中看到的现象:两个int*指针实际地址差4字节(刚好是一个int的长度),直接相减得到的结果是1——因为这两个指针之间刚好隔了1个int类型的元素。

2. mySizeof宏的工作逻辑

宏的完整逻辑分三步:

  • 第一步:&type拿到变量的首地址,这个指针的类型是指向变量对应类型的指针,比如传入int变量y时,&y是int*类型。
  • 第二步:&type +1 按照指针运算规则,会向后偏移一个对应类型变量的长度,刚好指向当前变量内存后面紧邻的位置。
  • 第三步:把前后两个地址都强转成char*类型再相减,得到最终的字节长度结果。

3. char*强转的作用

C标准明确规定sizeof(char)的结果恒为1,也就是说char*类型的指针运算单位是1字节。
当我们把两个地址都转成char*之后,指针相减得到的结果就是两个地址之间间隔的char类型元素个数,也就是间隔的字节数,刚好等于原类型的大小。
如果不加这个强转,就会出现测试代码里的情况:两个同类型指针相减永远得到1,根本算不出实际字节长度。


内容的提问来源于stack exchange,提问作者Chris Bao

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 14:45:32