在 c/c++ 中,指针的步长取决于它指向的数据类型,比如在以下代码中,结果完全不同:

#include <cstdio>

int main()
{
    char array[] = {0,1,2,3,4,0,0,0};

    printf("%i\n", *(array + 1));       // 1
    printf("%i\n", *((int*)array + 1)); // 4
}
  • char* 指针步长为1个字节。
  • int* 指针步长为4个字节。

所以在对(int*)nums + 1时,它会从数组的起始地址向后移动4个字节,而不是1个字节。这种步长差异直接导致了访问到的数据位置不同,输出了不同的结果。

从数组下标的角度或许更容易理解,当使用[]运算符对T取值时,实际读取的地址是 offset * sizeof(T),即:

#include <cstdio>

int main()
{
    char array[] = {0,1,2,3,4,0,0,0};

    printf("%i\n", array[1]);  // 1

    int *intptr = (int*)array;
    printf("%i\n", intptr[1]); // 4
}

所以在对指针做算术运算时,需要特别注意指针的类型,转为char*或者uintptr_t再进行运算是一个安全且通用的做法。