Почему p, * p, & * p имеют одинаковое значение, когда p является двумерным массивом? - PullRequest
0 голосов
/ 05 июля 2019

Когда p является указателем на массив, почему:

*p == p == &*p

Простая программа, просто двумерные массивы в c ++:

int p[][3] = {{1,2,3}};
cout << p << " " << *p << " " << &*p;

результат: 0x22fe20 0x22fe20 0x22fe20

Ответы [ 4 ]

3 голосов
/ 05 июля 2019

Массив p распадается на указатель на свой первый элемент при его печати. Это так же, как &p. Что касается &*p, то это адрес того, на что указывает разыменованный p. Который снова является первым элементом - так же, как первые два.

Тип отличается, хотя. Даже если адреса совпадают. p - это массив, но &p - указатель на int массив.

1 голос
/ 05 июля 2019

Когда используется значение массива (в данном случае p), оно неявно преобразуется в указатель на первый элемент (такой же, как &p[0]).Такое преобразование называется затухающим.

Кроме того, первый элемент массива находится по тому же адресу, где находится массив.

  • p распадается на &p[0].Это адрес первого элемента p, который совпадает с адресом самого массива p.
  • *p Здесь p сначала уменьшается до &p[0], поэтому полноеВыражение эквивалентно *&p[0].*& отменяет друг друга (по определению в C; C ++ использует другую формулировку, но эффект тот же). Таким образом, это lvalue до p[0], то есть первый элемент массива.В этом случае этот элемент является другим массивом, и поэтому его значение уменьшается до указателя на первый элемент (т. Е. &p[0][0]).Поскольку адрес первого элемента совпадает с адресом массива, адрес p[0][0] совпадает с адресом p[0], который совпадает с адресом p.
  • &*pКак и прежде, &* отменяют друг друга, и результат такой же, как при использовании только p.

В памяти 2D-массив 4x4 выглядит следующим образом:

  *
..0000111122223333..
  XXXXXXXXXXXXXXXX
  YYYY
  Z

На этой диаграмме каждый столбец представляет область памяти.В столбцах, отмеченных X, хранится двумерный массив.

Каждый столбец, отмеченный 0, является элементом первого подмассива, а каждый столбец с 1 - элементами второго подмассива и т. Д.

В столбцах, отмеченных Y, хранится первый подмассив.

Столбец, отмеченный Z, является первым элементом первого подмассива.

Как вы можете заметить,X, Y и Z все начинаются с одного и того же адреса, помеченного *.Это адрес массива, адрес первого подмассива и адрес первого элемента первого подмассива.

0 голосов
/ 05 июля 2019

Если у вас есть массив, объявленный, например, так:

int a [] = {1, 2, 3};

, затем используется в выражениях (за редкими исключениями, например, дляоперанд оператора sizeof) указатель массива неявно преобразуется в указатель на его первый элемент.Таким образом, в этом выражении

std::cout << a;

совпадает с

std::cout << &a[0];

или совпадает с

std::cout << &*a;

В вашем примере *p является массивом {1,2,3} который представляет первый элемент массива p.

Используется как выражение в операторе

std::cout << *p;

. Он преобразуется в адрес первого элемента, то есть адрес первого элемента равен 1.

Все эти адреса указывают на начало экстента, выделенного массиву.Таким образом, хотя типы, например, выражения p и выражения *p различны (первое выражение имеет тип int ( * )[3], а второе выражение имеет тип int *), тем не менее их значения равны.

0 голосов
/ 05 июля 2019

p - указатель на начало массива.

*p - указатель на первый массив в этом массиве (он же начало массива)

&*p - это то же самое, что и p, синтаксически.

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