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

使用指针访问数组元素的疑问:为何*(ptr+i)对应数组下一个索引

为什么指针加法在不同类型数组中都能指向正确的下一个元素?

这是个非常好的问题,刚好触及了C/C++指针算术的核心设计逻辑——指针加法是「类型感知」的,它不会固定偏移1字节,而是根据指针指向的元素类型大小来计算实际的内存偏移量。

让我一步步帮你拆解清楚:

1. 数组名到指针的隐式转换

首先要明确:在几乎所有场景下,数组名会自动转换成指向数组第一个元素的指针:

  • arr1(原本是int[5]类型)会被转换成int*类型的指针,指向arr1[0];
  • arr2(原本是char[5]类型)会被转换成char*类型的指针,指向arr2[0]。

2. 指针加法的核心规则

当你对一个T*类型的指针执行ptr + n操作时(T是任意数据类型,n是整数),实际的内存地址偏移量是:

偏移字节数 = n * sizeof(T)

这个规则是C/C++语言内置的,目的就是让指针操作完美适配数组的连续存储结构——因为数组的每个元素都会占用sizeof(T)字节的连续内存空间。

对应你的代码例子:

  • 对于arr1(int*类型):假设你的平台上sizeof(int) = 4(这是大多数现代平台的情况),那么arr1 + 1会把地址偏移1 * 4 = 4字节,刚好跳过一个完整的int元素,直接指向arr1[1]的内存位置,所以*(arr1 + 1)自然就等于arr1[1]的值2。
  • 对于arr2(char*类型):C标准规定sizeof(char)永远是1,所以arr2 + 1只偏移1字节,指向arr2[1]的位置,这和你已经理解的逻辑一致。

3. 数组索引的本质

其实你平时写的arr[i],本质上就是*(arr + i)的语法糖——这也是为什么不管数组元素是什么类型,arr[i]都能正确访问第i个元素的原因,底层都是用这种类型感知的指针加法实现的。

直观验证的小技巧

你可以打印指针的实际地址来亲眼看到偏移量差异:

#include <iostream>
using namespace std;

int main() {
    int arr1[5] = {1,2,3,4,5};
    char arr2[5] = {'a','b','c','d','e'};
    
    cout << "arr1 起始地址: " << (void*)arr1 << endl;
    cout << "arr1+1 的地址: " << (void*)(arr1 + 1) << endl; // 地址差4字节(取决于int的大小)
    
    cout << "\narr2 起始地址: " << (void*)arr2 << endl;
    cout << "arr2+1 的地址: " << (void*)(arr2 + 1) << endl; // 地址差1字节
    return 0;
}

运行这段代码,你会清晰看到不同类型指针加1后,地址偏移的字节数完全对应元素的类型大小。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:56:37