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

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

01.03.2025, 23:14. Показов 2373. Ответов 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
6241 / 2954 / 1047
Регистрация: 01.06.2021
Сообщений: 10,979
01.03.2025, 23:30
Цитата Сообщение от Geek Geekson Посмотреть сообщение
и как тогда правильно объявлять p (если без auto)
с auto у тебя по сути вот это:
C++
1
int (*p)[cols] = array;
а не
C++
1
int **p = array;
1
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
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
6241 / 2954 / 1047
Регистрация: 01.06.2021
Сообщений: 10,979
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
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
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
13192 / 6827 / 1822
Регистрация: 18.10.2014
Сообщений: 17,277
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
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
02.03.2025, 00:18
Цитата Сообщение от Geek Geekson Посмотреть сообщение
Тогда непонятно почему вот это (12 строка)
В 12-ой строке, int(*)[cols] - это указатель на первый элемент массива(в данном случае верхнего уровня).
Полный тип массива - int[rows][cols]
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13192 / 6827 / 1822
Регистрация: 18.10.2014
Сообщений: 17,277
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
13192 / 6827 / 1822
Регистрация: 18.10.2014
Сообщений: 17,277
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
13192 / 6827 / 1822
Регистрация: 18.10.2014
Сообщений: 17,277
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
Ответ Создать тему
Новые блоги и статьи
Знаешь почему 90% людей редко бывают счастливыми?
kumehtar 14.04.2026
Потому что они ждут. Ждут выходных, ждут отпуска, ждут удачного момента. . . а удачный момент так и не приходит.
Фиксация колонок в отчете СКД
Maks 14.04.2026
Фиксация колонок в СКД отчета типа Таблица. Задача: зафиксировать три левых колонки в отчете. Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) / / . . .
Настройки VS Code
Loafer 13.04.2026
{ "cmake. configureOnOpen": false, "diffEditor. ignoreTrimWhitespace": true, "editor. guides. bracketPairs": "active", "extensions. ignoreRecommendations": true, . . .
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
Подстановка значения реквизита справочника в табличную часть документа
Maks 10.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: при выборе сотрудника (справочник Сотрудники) в ТЧ документа. . .
Очистка реквизитов документа при копировании
Maks 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях. Задача: при копировании документа очищать определенные реквизиты и табличную. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru