Почему указатель ведет себя так в C++

Я нашел эту программу в конкурсном вопросном листе:

#include <iostream>
void main() 
{    
    int a[5] = { 1, 2, 3, 4, 5 };
    int *ptr = (int*)(&a + 1);
    printf("%d %d ",*(a + 1), *(ptr - 1));
}

Выход 2 5

теперь, когда я меняю 5-ю строку на int *ptr=(int*)(&a); а также printf("%d %d ",*(a + 1), *(ptr));

Выход становится 2 1

В первом случае ptr получил последний адрес array+1 а во втором случае ptr получил тот же адрес массива (адрес a).

Я сомневаюсь, почему это назначение показывает другой тип поведения, когда а увеличивается и назначается ptr и когда a назначен на ptr без приращения?

3 ответа

Решение

Когда вы берете адрес массива, вы получаете указатель на массив из 5 дюймов (то есть int(*)[5]). Когда вы увеличиваете этот указатель, он перемещается на размер массива 5 дюймов. Таким образом, он указывает на следующий массив в последовательности массивов (если у вас действительно была последовательность массивов). Затем, когда вы конвертируете этот указатель в int*становится указателем на первый int второго (несуществующего) массива, который является одним элементом после последнего элемента первого массива. Вот что происходит с вашим первым примером.

Во втором примере вы не увеличиваете указатель на массив, поэтому при преобразовании его в int*становится указателем на первый int в массиве.

&a указатель на целочисленный массив размером 5, а ptr является int*, Таким образом, &a + 1 увеличение на размер int[5], а указатель арифметический на int* изменяет значение указателя на кратные sizeof(int), Таким образом, &a + 1 указывает на адрес, который 5*sizeof(int) с адреса a, Кастинг это к int* ptr и делать ptr-1 дает вам адрес a[4],

&a + 1;

Здесь просто a ссылается на базовый адрес массива, то есть адрес первого элемента. Когда ты сказал a+1 Компилятор увидит +1 применительно к pointer to an int, Таким образом, он будет увеличиваться на смещение, что заставит его перейти к следующему целому числу.

Тем не менее, когда вы говорите, &a, это означает адрес этого элемента массива (который имеет тип int [5]). Таким образом, добавление единицы к нему означает, что следующее смещение будет следующим массивом этого типа, то есть косвенно до конца одного массива. Получение адреса элемента one-past-array не проблема, пока вы не разыграете его.

Другие вопросы по тегам