-->

How exactly pointer subtraction works in case of i

2019-01-24 21:37发布

问题:

#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;
}

For the first printf() statement the output will be 5 according to Pointer subtraction confusion

What about the second printf() statement, what will be the output?

回答1:

To quote C11, chapter §6.5.6, Additive operators

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.

So, when you're doing

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

both ptr1 and ptr2 are pointers to int, hence they are giving the difference in subscript, 5. In other words, the difference of the address is counted in reference to the sizeof(<type>).

OTOH,

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

both ptr1 and ptr2 are casted to a pointer to char, which has a size of 1 byte. The calculation takes place accordingly. Result: 20.

FWIW, please note, the subtraction of two pointers produces the result as type of ptrdiff_t and you should be using %td format specifier to print the result.



回答2:

If you have two pointers of type T that point to elements of the same array then the difference of the pointers yields the number of elements of type T between these pointers

So the first output statement

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

outputs 5 - the number of elements of type int between pointers ptr1 and ptr2.

It is the so-called pointer arithmetic.

Pointers (char*)ptr1 and (char*)ptr2 have the same values as the original pointers ptr1 and ptr2 but they consider (reinterpret) the memory extent as an array of type char each element of which has size equal to sizeof( char ). In C sizeof( char ) is always equal to 1. Thus the difference ( char * )ptr2 - ( char * ) ptr1 gives the number of elements of type char that can fit the memory extent. It is evident that sizeof( char ) is not greater than sizeof( int ). So the same memory extent can accomodate more elements of type char than of type int. If for example sizeof( int ) is equal to 4 then the memory extent can accomodate 5 * sizeof( int ) elements of type char that is 20.



回答3:

Pointer arithmetics is always in the units of the base type.

In your case you have

int *ptr1 = ...

Then doing ptr1 + 5 will add sizeof(*ptr1) * 5 bytes to the pointer ptr1. Considering that sizeof(*ptr1) (which is the same as sizeof(int)) is 4, then you get 4 * 5 which equals 20 bytes.



回答4:

Each array element is an int and there are 5 elements between both the pointers. Thus there will be 5*sizeof(int) amount of bytes in between both the pointers.