为何char指针大小为8字节却仅递增1字节?底层原理探究
代码示例
void main() { char var = 10; char *ptr = &var; printf("Pointer address before increment:%p\n", ptr); printf("sizeof(ptr):%d\n", sizeof(ptr)); ptr++; printf("Pointer address after increment:%p\n", ptr); printf("sizeof(ptr):%d\n", sizeof(ptr)); }
输出结果
Pointer address before increment:0x7fffb997144f sizeof(ptr):8 Pointer address after increment:0x7fffb9971450 sizeof(ptr):8
问题解答
1. 指针自身大小和指向类型大小是完全独立的两个概念
- 指针本质是存储内存地址的变量:在64位系统下,内存地址是64位的,所以指针变量本身占8字节(32位系统则是4字节),
sizeof(ptr)测量的就是这个存储地址的变量的空间大小,和它指向的数据类型毫无关系。 - 指针自增的偏移量由指向的类型大小决定:C语言设计指针自增的逻辑是让它直接指向「下一个同类型元素的起始地址」。
char类型本身占1字节,所以ptr++会让地址加1;如果是int*指针,自增就会加4字节(假设int占4字节),这样指针才能精准定位到下一个int元素的位置。
2. 底层原理:编译器的类型推导与指令生成
- C语言的指针是带「类型信息」的,编译器在编译阶段就会根据指针的指向类型,把
ptr++这类操作翻译成对应偏移量的汇编指令:比如char*自增对应add rax, 1,int*自增对应add rax, 4(64位环境)。 - 这种设计是为了类型安全和易用性:一方面避免指针越界访问错误类型的内存,另一方面让数组遍历、结构体成员访问这类操作更简洁——比如遍历数组时,不用手动计算
sizeof(type)来做偏移,直接ptr++就能跳到下一个元素。
举个对比例子更直观
如果把代码改成int*指针,就能看到明显的区别:
int num = 20; int *p = # printf("Before: %p\n", p); // 假设输出0x7fffb997144c p++; printf("After: %p\n", p); // 输出0x7fffb9971450,地址增加了4字节
内容的提问来源于stack exchange,提问作者Dheeraj
相关产品推荐
相关产品推荐

