Почему значения разные?Указатель C ++ - PullRequest
4 голосов
/ 26 сентября 2019

Я искал решение, чтобы узнать длину массива в C ++.Одно из решений, которое я нашел, это

int arr[] = {1,2,3,4,5,6};
int size = *(&arr+1)-arr; //size is the length of the array

Я был перепутан между &arr и arr, так как оба дают базовый адрес массива.Снова гуглил и обнаружил, что &arr + 1 дает адрес следующего блока памяти, который не является частью массива, где arr + 1 дает адрес следующего элемента в массиве.

Я написал следующий код дляпроверить разницу между &arr и arr:

int arr[] = {1,2,3,4,5,6};
printf("value of &arr + 1 - &arr = %d\n", &arr + 1 - &arr);
printf("value of *(&arr + 1) - arr = %d\n", *(&arr + 1) - arr);

Ответ на первый printf равен 1, где вторым printf дает 6.Это та часть, которая меня смущает: поскольку &arr и arr содержат базовый адрес одного и того же массива, почему результаты отличаются?

Ответы [ 2 ]

6 голосов
/ 26 сентября 2019

Поскольку "& arr" и "arr" содержат базовый адрес одного и того же массива, почему результаты отличаются?

Поскольку тип отличается,На арифметику указателя влияет тип указателя и, более конкретно, тип указанного объекта.

&arr - указатель на массив из 6 int.Добавление 1 к этому приращению к следующему массиву из 6 дюймов (если это был элемент массива массивов).

arr, хотя и является массивом, затухает, чтобы указывать на первый элемент массивакогда его значение используется, например, в арифметическом выражении указателя.Затухшее значение является указателем на int и добавлением 1 к нему перемещает указатель на следующее целое число.

PS Вместо этого можно использовать std::size.Или std::extent до C ++ 17.Или sizeof arr / sizeof *arr pre-C ++ 11.

*(&arr + 1) - arr, вероятно, работает, но технически перенаправляется через указатель конца конца (на объект, который не существует), что обычно является неопределенным поведением.Я не уверен, может ли быть какое-то исключение из правила, учитывая, что значение используется только для затухания указателя.

0 голосов
/ 26 сентября 2019

& arr и arr - разные указатели.arr - адрес первого элемента массива "arr".Но & arr это адрес указателя обр.В адресе & arr есть адрес массива "arr".Так что это адрес адреса массива.Таким образом, & arr является неожиданным, а * (& arr + 1) также является неожиданным.Поскольку мы не знаем, какое значение сохраняется в следующем адресе & arr.

Позвольте мне объяснить ваши два утверждения printf.& arr + 1 - & arr всегда возвращает 1. Поскольку он добавляет единицу к & arr и снова вычитает & arr, результат равен 1. * (& arr + 1) - arr возвращает неожиданный результат.Поскольку * (& arr + 1) непредсказуемо, а arr также непредсказуемо, поэтому результат непредсказуем.

Вот почему эти два результата отличаются.

Извините за не удобный для пользователя ответ.Спасибо, С наилучшими пожеланиями.

Джин Йи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...