C++通过指针算术计算数组元素个数的原理疑问
C++ 指针减法计算数组长度的运行原理
你给出的示例代码如下:
#include <iostream> using namespace std; int main() { int array[10] = {0, 9, 1, 8, 2, 7, 3, 6, 4, 5}; int stretch = *(&array + 1) - array; cout << "Array is consists of: " << stretch << " numbers" << endl; cout << "Hence, Length of Array is: " << stretch; return 0; }
核心运行逻辑
你的猜测是完全正确的:C++的指针算术默认以指向元素为单位计算,同类型指针相减直接返回元素个数而非字节差值。这个实现的核心依赖两个底层规则:
- 指针算术的基本单位是指向类型的大小:两个相同类型的指针相减,返回值是两者之间相差的元素个数,而非字节差值。系统会自动将两个指针的字节差值除以指针指向类型的
sizeof值,得到最终结果。 - 数组取地址的类型特殊:
&array的类型是int (*)[10],也就是指向「长度为10的int数组」的指针,而非指向单个int元素的指针,它的步长是整个数组的字节大小sizeof(int[10])。
代码逐段拆解
我们对核心计算行int stretch = *(&array + 1) - array;做分步解析:
&array + 1:基于&array的数组指针类型,加1操作会跳过一整个长度为10的int数组,指向数组最后一个元素后方的地址*(&array + 1):对数组指针解引用得到int[10]类型的数组,数组参与运算时会自动退化为指向首元素的int*指针,指向的地址还是刚才数组末尾后的位置array作为右值参与运算时,同样会退化为指向数组首元素的int*指针- 两个
int*指针相减,系统自动计算地址字节差值除以sizeof(int),得到元素个数10
手动计算不符的原因
你手动计算得到的是两个地址的字节差值,而代码里的指针减法自动做了除以sizeof(int)的转换。比如常见的32位int环境下,两个地址的字节差值应为40(对应十六进制0x28),除以4得到10,和代码运行结果一致。你拿到的十六进制1C(十进制28)大概率是测试环境下的特殊情况,或者是打印地址时选错了输出对象导致的误差,核心逻辑不会变。
注意事项
这个计算方法只适用于栈上分配的原始数组,如果数组已经退化为指针(比如作为函数参数传递后),就无法用这个方法计算长度,因为普通指针没有关联的数组长度信息。
内容的提问来源于stack exchange,提问作者matthew abbott
相关产品推荐
相关产品推荐

