Почему результат использования `int (* p) [5]` настолько запутан? - PullRequest
4 голосов
/ 30 ноября 2011

Я знаю, что int (*p)[5] означает указатель, который указывает на массив из 5 дюймов. Поэтому я кодирую эту программу ниже:

#include <iostream>
using namespace std;

int main()
{
  int a[5]={0,1,2,3,4};
  int (*q)[5]=&a;
  cout<<a<<endl;         
  cout<<q<<endl;
  cout<<*q<<endl;        
  cout<<**q<<endl;
  return 0;
}

На моей машине результат:

0xbfad3608
0xbfad3608       //?__?
0xbfad3608
0

Я понимаю, что *q означает адрес a[0], а **q означает значение a[0], но почему q имеет то же значение, что и a и *q? По моему бедному разуму, это должен быть адрес их! Я полностью сбит с толку. Кто-нибудь, пожалуйста, помогите мне. Пожалуйста!

Ответы [ 3 ]

8 голосов
/ 30 ноября 2011

Посмотрите на это так:

   q == &a
   *q == a
   **q == *a

Вы не пробовали печатать &a. Если вы это сделаете, вы увидите, что оно имеет то же значение, что и a. Поскольку &a == a, q == &a и *q == a, по транзитивности q == *q.

Если вы хотите узнать, почему &a == a, посмотрите Почему адрес переменной массива такой же, как и у нее?

2 голосов
/ 30 ноября 2011

q и &a являются указателями на массив.

*q и a являются "массивом".Но вы не можете передать массив функции (а std::ostream::operator<< - функция);Вы действительно передаете указатель на первый элемент, который создается неявно (называется распадом указателя).Таким образом, *q и a становятся указателями на первый элемент массива.

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

1 голос
/ 30 ноября 2011

Это потому, что array автоматически преобразуется в pointer, который просто имеет значение адреса array.Поэтому, когда вы пытаетесь распечатать распечатку array, используя <<a или <<*q, вы фактически печатаете ее адрес.

...