c++ - указатели - указатель на двумерный массив си




Каков тип указателя на 2D-массив? (3)

Каков тип [...]

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

int main()
{
    int arr[2][3] = {{0,1,2}, {3,4,5}};  // <-- direct complete initialized here

    auto ptr = arr;                     // <-- address assignment only

    cout << "arr: " << typeid(arr).name() << endl;
    cout << "ptr: " << typeid(ptr).name() << endl;
    return 0;
}

Я должен признать, что выход

arr: A2_A3_i
ptr: PA3_i

кажется, не очень читабельна на первый взгляд (по сравнению с некоторыми другими языками), но в сомнении это может помочь. Это очень компактно, но к нему скоро можно привыкнуть. Кодировка зависит от компилятора, в случае, если вы используете gcc, вы можете прочитать Chapter 29. Demangling чтобы понять, как это сделать.

Редактировать:

некоторые эксперименты с некоторой функцией simple_cpp_name такие как рудиментарный взлом

#include <typeinfo>
#include <cxxabi.h>
#include <stdlib.h>
#include <string>

std::string simple_cpp_name(const std::type_info& ti)
{
    /// simplified code extracted from "Chapter 29. Demangling"
    /// https://gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html
    char* realname = abi::__cxa_demangle(ti.name(), 0, 0, 0);
    std::string name = realname;
    free(realname);
    return name;
}

покажет вам, что auto &rfa = arr; делает rfa с тем же типом, что и arr который является int [2][3] .

Я знаю, что следующее неверно:

int arr[2][3] = {}; //some array initialization here
int** ptr;
ptr = arr;

Но я очень удивлен, что на самом деле работают следующие строки

int arr[2][3] = {}; //some array initialization here
auto ptr = arr;
int another_arr[2][3] = {}; //some array initialization here
ptr = another_arr;

Может ли кто-нибудь объяснить, что такое тип, назначенный ptr во втором блоке кода, и что произошло под ним?


В

auto ptr = arr;

arr распадается на указатель на свой первый элемент обычным способом; это эквивалентно

auto ptr = &arr[0];

Поскольку arr[0] представляет собой массив из трех int s, это делает ptr int (*)[3] - указателем на int[3] .

another_arr распадается точно так же, поэтому в

ptr = another_arr;

обе стороны назначения имеют тип int (*)[3] , и вы можете назначить T* T* для любого типа T

Указатель на arr имеет тип int(*)[2][3] .

Если вам нужен указатель на массив, а не указатель на первый элемент массива, вам нужно использовать & :

auto ptr = &arr; 

Ну, массивы распадаются на указатели при использовании практически везде. Поэтому, естественно, в вашем фрагменте кода также есть распад.

Но только размер «внешнего большинства» массива распадается на указатель. Поскольку массивы являются строковыми, вы получаете int (*)[3] как тип указателя, который является указателем на одномерный массив, а не двумерный массив. Он указывает на первый «ряд».

Если вы хотите, чтобы вывод ptr был указателем на массив, а затем используйте адрес оператора:

auto ptr = &arr;

Теперь ptr является int(*)[2][3] .





multidimensional-array