Почему один код выдает “Значение типа char(*)[4] нельзя использовать для инициализации сущности типа char**”, а другой работает?

138
22 сентября 2019, 19:20

Вопрос такой, почему один код выдает "Значение типа char(*)[4] нельзя использовать для инициализации сущности типа char**"

char a[] = "abc";
char** cpp = &a;

а другой код проходит

char a[] = "abc";
char* cp = a;
char** cpp = &cp;

И подвопрос - круглые скобки в char(*)[4] играют какую-то роль?

Answer 1

Во втором случае вы сначала делаете указатель, а потом указатель на указатель. char* cp=a; в принципе равносильно char* cp=&a[0]; Собственно именно по этому первый вариант не работает. Круглые скобки показывают нам, что это указатель на массив чаров.

Answer 2

В языке С++ переменную типа T можно инициализировать только значением типа T или значением, неявно приводимым к типу T.

Значение &a имеет тип char (*)[4] и не может быть использовано для инициализации указателя типа char **. Это разные, неприводимые типы, никакого отношения друг к другу не имеющие.

Значение &cp имеет тип char ** и может быть использовано для инициализации указателя типа char **. Это одинаковые типы

Вот и все. Вам компилятор все подробно расписал.

Скобки в char (*)[4] роль играют. char (*)[4] и char *[4] - разные типы.

Answer 3

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

На рисунке ниже показан массив a и указатель на его первый элемент cp:

Когда вы пишете &a - вы получаете указатель на массив. Когда вы пишете &cp - вы получаете указатель на указатель. Массив не является указателем, поэтому эти два типа неприводимы друг к другу.

Answer 4

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

char* cp = a;

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

Но &a это адрес обьекта_массива имеющий тип char(*)[4], т.е. указатель на массив символов с четыремя элеметами типа char, а не указатель на адрес обьекта типа char(указатель на указатель). Точно также можно написать:

std::vector<char> a;
char* pv = &a[0]; // адрес первого элемента последовательности
char** pp = &pv;  // адрес указателья

Но нельзя:

char** ppv = &a;

поскольку &a это std::vector<char>*, и никак не может преобразиться в char**. P.S. Разница только в том, что имя вектора не интерпретируется как адрес первого элемента посдеовательности

READ ALSO
Открытие и считывание файла

Открытие и считывание файла

При вот таком вот способе открытия файла выдает ошибку следующего характера: (фото 1 и фото 2)Как можно исправить? Спасибо

112
Qt. Начало работы

Qt. Начало работы

Установил Qt Creator версии 48

109
QComboBox Delegate и отображение данных в QTableView

QComboBox Delegate и отображение данных в QTableView

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

106