在整数数组的情况下,指针减法究竟是如何工作的?

How exactly pointer subtraction works in case of integer array?

#include<stdio.h>
int main()
{
    int arr[] = {10, 20, 30, 40, 50, 60};
    int *ptr1 = arr;
    int *ptr2 = arr + 5;
    printf("Number of elements between two pointer are: %d.", 
                                (ptr2 - ptr1));
    printf("Number of bytes between two pointers are: %d",  
                              (char*)ptr2 - (char*) ptr1);
    return 0;
}

对于第一个 printf() 语句,输出将是 5 根据 Pointer subtraction confusion

第二个printf()语句呢,输出结果是什么?

引用 C11,章节 §6.5.6,加法运算符

When two pointers are subtracted, both shall point to elements of the same array object, or one past the last element of the array object; the result is the difference of the subscripts of the two array elements.

所以,当你在做的时候

printf("Number of elements between two pointer are: %d.", 
                            (ptr2 - ptr1));

ptr1ptr2都是指向int的指针,因此它们给出了下标的差异,5。换句话说,地址的差异被计算在引用中到 sizeof(<type>).

OTOH,

 printf("Number of bytes between two pointers are: %d",  
                          (char*)ptr2 - (char*) ptr1);

ptr1ptr2 都被 转换为 指向 char 的指针,其大小为 1 字节。相应地进行计算。结果:20.

FWIW,请注意,两个指针相减产生的结果为 ptrdiff_t 类型,您应该使用 %td 格式说明符来打印结果。

指针算法始终以基类型为单位。

在你的情况下你有

int *ptr1 = ...

然后执行 ptr1 + 5 会将 sizeof(*ptr1) * 5 字节 添加到指针 ptr1。考虑到 sizeof(*ptr1)(与 sizeof(int) 相同)是 4,那么您会得到 4 * 5,等于 20 字节。

每个数组元素都是一个 int,两个指针之间有 5 个元素。因此,两个指针之间将有 5*sizeof(int) 个字节数。

如果你有两个 T 类型的指针指向同一个数组的元素,那么指针的差异会产生这些指针之间的 T 类型元素的数量

所以第一个输出语句

printf("Number of elements between two pointer are: %d.", 
                            (ptr2 - ptr1));

输出 5 - 指针 ptr1ptr2 之间类型 int 的元素数。

就是所谓的指针运算

指针 (char*)ptr1(char*)ptr2 与原始指针 ptr1ptr2 具有相同的值,但它们将内存范围视为(重新解释)类型数组char 每个元素的大小等于 sizeof( char )。在 C 中 sizeof( char ) 总是等于 1。 因此,差异 ( char * )ptr2 - ( char * ) ptr1 给出了可以适合内存范围的类型 char 的元素数。很明显 sizeof( char ) 不大于 sizeof( int )。所以相同的内存范围可以容纳比 int 类型更多的 char 类型的元素。例如,如果 sizeof( int ) 等于 4,则内存范围可以容纳 5 * sizeof( int ) 类型 char 的元素,即 20.