对指针的引用执行算术运算会发生什么?&arr+1如何计算数组长度
C语言数组长度计算中
&arr + 1的原理解析 你给出的数组长度计算代码的核心在于利用了C语言数组和指针的类型差异,虽然arr和&arr的数值完全一致,但二者类型不同,指针算术的步长也完全不同:
1. arr与&arr的类型差异
arr是类型为int[5]的数组,在绝大多数表达式运算场景下会隐式降级为int*类型的指针,指向数组首元素。因此arr + 1的步长为sizeof(int),移动后指向数组第二个元素,这和你已知的指针运算规则一致。&arr的类型是int (*)[5],即指向整个长度为5的int数组的指针,它的步长为sizeof(int[5]),也就是整个数组占用的内存总大小。
二者数值相同是因为整个数组的起始地址和数组首元素的起始地址完全重合,但类型差异决定了做算术运算时的行为完全不同。
2. &arr + 1的运行逻辑
指针算术的偏移量由指针的类型决定:&arr是指向整个数组的指针,&arr + 1就会跳过一整个int[5]的内存空间,刚好指向arr数组末尾之后的第一个内存地址,数值等价于(char*)arr + 5 * sizeof(int)。
3. 长度计算的完整推导
我们逐段拆解*(&arr + 1) - arr的运算过程:
&arr + 1得到指向数组末尾后第一个位置的int(*)[5]类型指针- 对该指针执行解引用操作
*(&arr + 1),得到类型为int[5]的数组(该数组仅为地址占位,没有实际分配的有效元素) - 该数组参与减法运算时,再次隐式降级为
int*类型的指针,指向数组末尾后第一个int元素的地址 - 两个
int*类型的指针相减,返回的是二者之间相差的int元素个数:末尾后地址减去首元素地址,刚好就是数组的总长度5。
注意事项
该计算方法仅能直接作用于原数组名本身,如果数组已经隐式降级为普通指针(比如作为参数传入函数后,形参的实际类型是int*而非int[5]),该方法会失效,无法得到正确的数组长度。
内容的提问来源于stack exchange,提问作者user3554898
相关产品推荐
相关产品推荐

