C/C++. Арифметика указателей

Арифметика указателей проста в силу их "адресной" природы:
- указатели можно складывать и вычитать с константными целочисленными значениями, например вот так:

#include <stdio.h>

int main() {
   
    int array[5], *ptr1, *ptr2, size;
   
    ptr1 = &array[0];
    ptr2 = ptr1 + 5;
    size = ptr2 - ptr1;
    

    // size = 5
    printf("\nsize = %d", size);
   
    return 0;
}


или вот так:

#include <stdio.h

int main() {
   
    int array[5], *ptr1, *ptr2, size;
   
    ptr1 = &array[5];
    ptr2 = ptr1 - 5;
    size = ptr2 - ptr1;

    
    // size = -5    
    printf("\nsize = %d", size);
   
    return 0;
}


- запрещено складывать указатели друг на друга, но разрешено вычитать, эту особенность удобно использовать при вычислении элементов массивов:

#include <stdio.h>

int main() {
  
    int array[5], *ptr1, *ptr2, size;
  
    ptr1 = &array[0];
    ptr2 = &array[5];
    // складывать указатели запрещено
    size = ptr2 - ptr1;
   
    // в данном случае не приходится дополнительно учитывать тип массива
    printf("\n1. size = %d", size);

    // альтернативные варианты
    printf("\n2. size = %d", sizeof(array)/sizeof(&array));
    printf("\n2. size = %d", sizeof(array)/sizeof(array[0]));
    printf("\n3. size = %d", sizeof(array)/sizeof(&array[0]));
    printf("\n4. size = %d", sizeof(array)/sizeof(int));
  
    return 0;
}


Обратите внимание, в данном случае не нужно дополнительно указывать тип массива, в отличии от альтернативных способов. Обратите внимание на тип переменной size - int - ее тип соответствует типу вычитаемых указателей, вообще для разности указателей выделяют специальный тип - ptrdiff_t в stddef.h. Этот тип используют для получения одинакового поведения (результата) данной реализации на разных платформах. Ниже приведен пример с учетом данного типа:

#include <stdio.h>
#include <stddef.h>

int main() {
 
    int array[5], *ptr1, *ptr2;
 
    ptr1 = &array[0];
    ptr2 = &array[5];
    // складывать указатели запрещено
    ptrdiff_t size = ptr2 - ptr1;
  
    // в данном случае не приходится дополнительно учитывать тип массива
    printf("\n1. size = %d", size);

    // альтернативные варианты
    printf("\n2. size = %d", sizeof(array)/sizeof(&array));
    printf("\n2. size = %d", sizeof(array)/sizeof(array[0]));
    printf("\n3. size = %d", sizeof(array)/sizeof(&array[0]));
    printf("\n4. size = %d", sizeof(array)/sizeof(int));
 
    return 0;
}