为何多级pointer内存大小一致,声明时却需用不同数量星号?
嘿,这个问题问到点子上了——很多刚接触指针的开发者都会混淆指针的大小和类型这两个核心概念,咱们一个个拆解清楚:
首先明确:指针的大小≠指针的类型
不管是普通指针还是多级指针,它们的大小都只由你的系统架构(比如32位是4字节,64位是8字节)和编译器实现决定,本质上都是用来存储内存地址的变量。但指针的类型(比如int*、char*、int**)才是决定它能做什么的关键,和大小完全是两码事。
疑问1:sizeof(b)和sizeof(c)相同,就能以相同方式解引用吗?
绝对不行!解引用的行为完全由指针的类型决定,和大小无关。举个实际的代码例子:
int num = 0x12345678; // 假设是32位系统,小端存储 int* b = # char* c = (char*)# // 强制转换后,sizeof(b)和sizeof(c)都是4字节 printf("*b的值:%x\n", *b); // 输出12345678,读取整个4字节的int值 printf("*c的值:%x\n", *c); // 输出78,只读取num的最低1字节
甚至如果指针类型和它指向的对象类型不匹配(除了void*这种通用指针),直接解引用可能触发未定义行为——比如把char*当成int*解引用,可能导致内存对齐错误,或者读取到完全错误的数据。
疑问2:多级指针只需用对应数量的星号声明吗?
没错,但要注意类型匹配。星号的数量代表指针的“层级”:
int* p:一级指针,指向int类型变量的地址int** pp:二级指针,指向int*类型指针的地址int*** ppp:三级指针,指向int**类型指针的地址
举个例子:
int val = 42; int* p = &val; int** pp = &p; int*** ppp = &pp; // 解引用要对应层级:三级指针需要三次解引用才能拿到最终值 printf("最终值:%d\n", ***ppp); // 输出42
声明时的星号数量必须和你要存储的指针层级匹配,否则编译器会直接报错。
疑问3:为什么多级指针大小一致,声明却要不同星号?
因为星号数量定义的是指针的类型信息,而不是大小。编译器需要这个信息做两件至关重要的事:
- 类型安全检查:比如你不能把
int**直接赋值给int*——编译器会立刻报错,避免你把一个“指针的地址”当成“普通变量的地址”来用,防止出现致命的内存访问错误。 - 正确处理解引用操作:虽然多级指针本身大小相同,但解引用二级指针时,编译器知道它指向的是一个一级指针,所以会正确读取一个指针大小的内存;而解引用一级指针时,编译器会读取对应类型(比如
int是4字节)的内存。如果没有类型区分,编译器根本不知道该怎么处理解引用。
简单说:大小是指针的“物理属性”,星号数量是指针的“逻辑属性”——两者各司其职,缺一不可。
内容的提问来源于stack exchange,提问作者Shobhit
相关产品推荐
相关产品推荐

