Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
3 / 3 / 0
Регистрация: 12.07.2022
Сообщений: 213

Точный тип двухмерного массива

01.03.2025, 23:14. Показов 2329. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Вопрос по встроенным массивам (да, я знаю что их лучше не использовать). Если создаём например двухмерный массив int, то сам его идентификатор по идее имеет тип int** - то есть указатель на указатель на тип int. Но если потом явно объявить такой указатель и попытаться присвоить ему идентификатор массива (строка 9) - то почему-то не компилится.

C++
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
 
int main()
{
    const int rows = 10;
    const int cols = 3;
    int array[rows][cols] = {};
 
    int **p = array;
    std::cout << p << '\n';
    std::cout << **p << '\n';
}
Если же вместо int **p объявить auto p - то всё компилится и работает. Почему, и как тогда правильно объявлять p (если без auto)?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
01.03.2025, 23:14
Ответы с готовыми решениями:

Точный тип данных
Подскажите пожаоуйста самый точный тип данных в который можно перевести из AnsiString В вопросах, связанных с Билдером, спрашивайте в...

Нужно ли сразу знать точный размер динамического массива, объявляемого в классе?
Можно ли сделать так? private: int i; char *p = new char; Или же ему надо сразу знать точный размер?

Передача двухмерного массива в функцию и изменение элемента массива
Такая проблема! Нужно передать в функцию двухмерный массив и изменить на елемент который равен 0 и если рядом по матрице находятса нули...

13
Эксперт функциональных языков программированияЭксперт С++
 Аватар для Royal_X
6136 / 2830 / 1039
Регистрация: 01.06.2021
Сообщений: 10,317
01.03.2025, 23:30
Цитата Сообщение от Geek Geekson Посмотреть сообщение
и как тогда правильно объявлять p (если без auto)
с auto у тебя по сути вот это:
C++
1
int (*p)[cols] = array;
а не
C++
1
int **p = array;
1
Заблокирован
01.03.2025, 23:57
Цитата Сообщение от Geek Geekson Посмотреть сообщение
Точный тип двухмерного массива
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include <type_traits>
 
int main(){
   const int rows = 10;
   const int cols = 3;
   using d2int = int[rows][cols];
   int array[rows][cols];
   std::cout << std::boolalpha;
   std::cout << std::is_same_v<d2int, decltype(array)> << std::endl;
   std::cout << std::is_same_v<d2int, int**> << std::endl;
   std::cout << std::is_same_v<d2int, int(*)[cols]> << std::endl; 
}
1
Эксперт функциональных языков программированияЭксперт С++
 Аватар для Royal_X
6136 / 2830 / 1039
Регистрация: 01.06.2021
Сообщений: 10,317
02.03.2025, 00:09
C++
1
2
auto p = array;
std::cout << std::is_same_v<decltype(p), int(*)[cols]> << std::endl;
true
0
Заблокирован
02.03.2025, 00:15
Geek Geekson, добавлю непосредственно к созданию указателя на приведенный массив:
C++
1
2
3
4
5
6
7
   #include <utility>
   // ...
   using pd2int = d2int*;
   
   pd2int pd2 = &array;
   std::cout << std::is_same_v<decltype(pd2), d2int*> << std::endl; // check
   std::cout << std::is_same_v<d2int, std::remove_pointer_t<pd2int>> << std::endl; // other check
0
3 / 3 / 0
Регистрация: 12.07.2022
Сообщений: 213
02.03.2025, 00:16  [ТС]
Тогда непонятно почему вот это (12 строка):

C++
1
std::cout << std::is_same_v<d2int, int(*)[cols]> << std::endl;
даёт false?
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12928 / 6796 / 1819
Регистрация: 18.10.2014
Сообщений: 17,197
02.03.2025, 00:18
Цитата Сообщение от Geek Geekson Посмотреть сообщение
Если создаём например двухмерный массив int, то сам его идентификатор по идее имеет тип int** - то есть указатель на указатель на тип int.
Нет. Ни в коем случае. Откуда вы такое взяли?

Двухмерный массив конвертируется в "указатель на одномерный массив", а не в "указатель на указатель".

Цитата Сообщение от Geek Geekson Посмотреть сообщение
Но если потом явно объявить такой указатель и попытаться присвоить ему идентификатор массива (строка 9) - то почему-то не компилится.
Вот поэтому и не компилится.

Цитата Сообщение от Geek Geekson Посмотреть сообщение
Почему, и как тогда правильно объявлять p (если без auto)?
C++
1
2
int array[rows][cols] = {};
int **p = array;
Либо

C++
1
int (*p)[cols] = array;
либо

C++
1
int (&p)[rows][cols] = array;
Оба варианта "правильные". О каком "правильно" вы говорите? Что вам нужно получить в результате?
0
Заблокирован
02.03.2025, 00:18
Цитата Сообщение от Geek Geekson Посмотреть сообщение
Тогда непонятно почему вот это (12 строка)
В 12-ой строке, int(*)[cols] - это указатель на первый элемент массива(в данном случае верхнего уровня).
Полный тип массива - int[rows][cols]
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12928 / 6796 / 1819
Регистрация: 18.10.2014
Сообщений: 17,197
02.03.2025, 00:22
Цитата Сообщение от Geek Geekson Посмотреть сообщение
Тогда непонятно почему вот это (12 строка):

C++
1
std::cout << std::is_same_v<d2int, int(*)[cols]> << std::endl;
даёт false?
Потому что d2int - это int[rows][cols], т.е. двухмерный массив . А int(*)[cols] - это указатель на одномерный массив. Это совершенно разные типы. Почему вас удивляет false?
0
3 / 3 / 0
Регистрация: 12.07.2022
Сообщений: 213
02.03.2025, 00:23  [ТС]
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Нет. Ни в коем случае. Откуда вы такое взяли?
Двухмерный массив конвертируется в "указатель на одномерный массив", а не в int**.
Как раз и пытался логическим путём: "одномерный массив конвертируется в указатель; значит 2-мерный массив (т. е. массив таких массивов) по идее конвертируется в указатель на указатель"

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Оба варианта "правильные". О каком "правильно" вы говорите? Что вам нужно получить в результате?
Да так, в образовательных целях, хотелось больше понимания.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12928 / 6796 / 1819
Регистрация: 18.10.2014
Сообщений: 17,197
02.03.2025, 00:32
Цитата Сообщение от Geek Geekson Посмотреть сообщение
Как раз и пытался логическим путём: "одномерный массив конвертируется в указатель; значит 2-мерный массив (т. е. массив таких массивов) по идее конвертируется в указатель на указатель"
Нет.

Логика тут простая: тип "массив" T[N] конвертируется в тип "указатель на элемент массива" T *.
Например: Тип массива int [N] => Тип элемента int => Получаем указатель int *.

В языке С и С++ двухмерный массив - это одномерный массив, составленный из одномерных массивов. То есть элементами двухмерного массива являются его одномерные подмассивы.

Применяем вышеприведенную логику и получаем: тип двухмерный массив T[N][M] конвертируется в "указатель на элемент массива", то есть в указатель на одномерный массив T (*)[M].
Например: Тип массива int [N][M] => Тип элемента int [M] => Получаем указатель int (*)[M].
3
3 / 3 / 0
Регистрация: 12.07.2022
Сообщений: 213
02.03.2025, 00:57  [ТС]
Ок, похоже меня немного переклинило.

Не по теме:

Перед этим разогревал картошку, со сковородки пара кусочков вывалилось на плиту, и у меня машинально левая рука потянулась нажать Ctrl+Z, чтобы отменить последнее действие (неаккуратное перемещение сковородки). :D

0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12928 / 6796 / 1819
Регистрация: 18.10.2014
Сообщений: 17,197
02.03.2025, 01:00
Цитата Сообщение от Geek Geekson Посмотреть сообщение
Ок, похоже меня немного переклинило. Никаких указателей на указатель там нет.
В массивах вообще нет никаких указателей. Указатели появляются в процессе дополнительных преобразований типов и являются посторонними сущностями, никакого непосредственного отношения к исходному массиву не имеющими.
0
3 / 3 / 0
Регистрация: 12.07.2022
Сообщений: 213
02.03.2025, 01:04  [ТС]
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
В массивах вообще нет никаких указателей. Указатели появляются в процессе дополнительных преобразований типов и являются посторонними сущностями, никакого непосредственного отношения к исходному массиву не имеющими.
Конечно. Просто сам идентификатор массива в некоторых условиях преобразуется в указатель на 0-й элемент. Думаю тема исчерпана.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
02.03.2025, 01:04
Помогаю со студенческими работами здесь

Сгенерировать массив размером 1000х1000 с float значениями
Приветствую, нужна ваша помощь. Требуется генерировать массив размером 1000х1000 с float значениями, как это сделать? Заранее спасибо

Как создать массив чтобы он сортировал числа которые введешь
как создать массив чтобы он сортировал числа которые введешь с меньшего до большего?

Как загнать в массив строку текста по буквам?
помогите пожалуйста кто-нибудь очень нада

Как научить IDE Cbuilder 6 понимать русский текст (массив строк с кириллицей преобразуется в знаки вопроса)?
Например массив строк с кириллицей он преобразует в занаки вопросы. Как это исправить?

Считать числа из файла и записать их в массив
Проблема следущая: нужна программа которая считывает числа типа double из файла (в моем случае это индексы валютного курса) и записывает их...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США. Нашел на реддите интересную статью под названием «Кто-нибудь знает, где получить бесплатный компьютер или. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru