Как назначить адрес массива указателю? - PullRequest
0 голосов
/ 05 февраля 2019
#include <iostream>

int main() {
  int arr[2] = {1, 2};
  int *p;
  // p = &arr; // Does not compile
  p = &arr[0]; // compiles
  std::cout << "&arr    = " << &arr << std::endl;
  std::cout << "&arr[0] = " << &arr[0] << std::endl;
}

Когда я пытаюсь напечатать адрес, оба печатают один и тот же адрес.Но когда я пытаюсь присвоить p = &arr, он не компилируется.Есть ли в стандарте что-то, что говорит против присвоения адреса массива указателю.Я просто хотел узнать причину, по которой p = &arr не компилируется?

Clang на самом деле говорит error: cannot initialize a variable of type 'int *' with an rvalue of type

Ответы [ 2 ]

0 голосов
/ 05 февраля 2019

Итак, у вас есть это:

arr[0] is the first item in memory
arr[1] is the second item in memory

Это эквивалентно следующему:

*((int*)arr + 0) is the first item in memory
*((int*)arr + 1) is the second item in memory

«Разыменование» указателя, это позволяет вам получить доступ к нужной памяти вместочисло, которое представляет его в памяти (указатель):

*((int*)arr + 0)

Это эквивалентно:

arr[0]

Если вам нужен адрес любого элемента, вы можете сделать, как показано здесь:

(int*)arr + Index

Адрес первого элемента является адресом памяти начала массива, поэтому адрес массива И первый элемент:

(int*)arr + 0 or just (int*)arr

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

p = &arr[0]; // compiles

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

p = &arr; // Does not compile

Тип адресаадрес массива:

int (*)[2];

Не:

int *p;

Вот почему онне компилируются, типы не совпадают.

Чтобы помочь с ошибками, связанными с типами, такими как эта, вы можете использовать typeid и decltype, в C ++ это позволяет вам печатать имя рассматриваемого типа.

Вот так

#include <iostream>

using namespace std;
int main()
{
    int arr[2] = {1, 2};

    std::cout<< "typeid ptr_array is " << typeid(decltype(&arr)).name() << "\n";
    std::cout<< "typeid ptr_item is " << typeid(decltype(&arr[0])).name() << "\n";

    return 0;
}

Результат:

ptr_array is PA2_i (Pointer to Array of size 2 with int)
ptr_item is Pi     (Pointer to int)

"P" из указателя typeid означает "A" означает массив.

Вы можетепоиграйте здесь: https://wandbox.org/permlink/RNNxjTMSUnLqUo6q

0 голосов
/ 05 февраля 2019

p = &arr;

- ошибка компилятора, поскольку тип &arr равен int (*)[2] - указатель на «массив из 2 int с».Следовательно, его нельзя присвоить p, тип которого int*.

Даже если &arr и &arr[0] оценивают одно и то же числовое значение, они являются разными типами.

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