|
-11 / 0 / 0
Регистрация: 14.07.2015
Сообщений: 30
|
||||||
Как передать двухмерный массив в функцию по ссылке?21.05.2018, 09:46. Показов 8829. Ответов 21
Преподаватель в универе просит написать функцию вида
0
|
||||||
| 21.05.2018, 09:46 | |
|
Ответы с готовыми решениями:
21
Как передать двухмерный массив в функцию?
|
|
|
|
| 21.05.2018, 10:27 | |
|
0
|
|
|
12 / 12 / 13
Регистрация: 18.05.2018
Сообщений: 67
|
||||||
| 21.05.2018, 11:59 | ||||||
0
|
||||||
|
285 / 176 / 21
Регистрация: 16.02.2018
Сообщений: 666
|
|
| 21.05.2018, 18:47 | |
|
0
|
|
|
285 / 176 / 21
Регистрация: 16.02.2018
Сообщений: 666
|
||
| 21.05.2018, 20:52 | ||
&a[0][0]), дальше в функции получается выход за границы массива. Обсуждалось тут Из одномерного массива сформировать двумерный массивДобавлено через 7 минут Кстати, тему от 2009-го года я даже находил, кажется. Но не стал её поднимать, т.к. слишком старая. Но раз уж она всплыла сейчас, то почему бы не написать про то, что там UB.
0
|
||
|
|
|||
| 21.05.2018, 21:05 | |||
|
В теме "Распространённые ошибки" удалили, так что лучше здесь. Чтобы не скакать по разным местам
Добавлено через 5 минут В ссылке (если имелась в виду она) http://eel.is/c++draft/expr.add#4 я не вижу подтверждения тому, что в коде UB
0
|
|||
|
285 / 176 / 21
Регистрация: 16.02.2018
Сообщений: 666
|
||
| 21.05.2018, 21:08 | ||
|
В теме Из одномерного массива сформировать двумерный массив я писал про то, почему в подобном коде UB.
0
|
||
|
|
||
| 21.05.2018, 21:30 | ||
|
Если ты имеешь в виду этот пост Из одномерного массива сформировать двумерный массив, то ты его неправильно интерпретируешь
Продублирую, чтобы перед глазами было: C++ int mm[50][2]; ... int *m=&mm[0][0]; for(int i=0;i<100;i++) std::cout<<m[i]<<' ';
В противном случае мы бы имели следующее. Есть указатель "int *ppp = &mm[0][1]". Формально такой указатель НЕ удовлетворяет условию "If the expression P points to element x[i] of an array object x with n elements", поскольку адрес этого выражения не совпадает ни с одним из адресов &mm[0], &mm[1] и т.п. (ведь в выдержке речь идёт про одномерный массив). При этом указатель "ppp + 1" совпадает с адресом элемента &mm[1]. Т.е. первая часть утверждения как бы ложна, а вторая как бы истина, а потому формально попадаем в "otherwise, the behavior is undefined", что выглядит заведомо абсурдным Поэтому данное правило не корректно применять к коду, который через обычный указатель обходит все элементы массива, потому что в стандарте описывается один тип указателя, а ты применяешь этот пункт к другому типу Вообще стандарт это вещь такая, где зачастую одного пункта недостаточно для того, чтобы понять точный смысл. Тут как в юридическом документе надо прочитать миллион разных пунктов, по совокупности которых как бы можно составить какое-то формально корректное утвеждение Добавлено через 4 минуты Та тема очень старая, в те времена ещё на форуме не было TheCalligrapher. Он умеет доступно и человеческим языком объяснить многие тонкости стандарта. Так что для полного понимания лучше бы спросить у него
1
|
||
|
285 / 176 / 21
Регистрация: 16.02.2018
Сообщений: 666
|
||||
| 21.05.2018, 21:39 | ||||
|
0
|
||||
|
|
||||
| 21.05.2018, 22:24 | ||||
|
Code $ g++-4.9.2 t.cc -c -std=c++11
<ok>Code $ g++-4.9.2 t.cc -c -std=c++11 t.cc:3:1: error: static assertion failed: Wrong number. static_assert( get_third( &a[0][0] ) == 4, "Wrong number." ); ^ Получается, что этот эксперимент не говорит ни о чём, если один компилятор ведёт себя так, а другой эдак
0
|
||||
|
285 / 176 / 21
Регистрация: 16.02.2018
Сообщений: 666
|
|||
| 21.05.2018, 22:35 | |||
|
Кликните здесь для просмотра всего текста
Могу притащить пример кода, который должен компилироваться со времён C++98, но в g++ он компилируется только с 6-й версии (2016 год выпуска, вроде).
0
|
|||
|
|
||||
| 21.05.2018, 22:59 | ||||
|
Тут даже допускается выход на один элемент за правую границу объекта-массива, но в нашем случае это не интересно, т.к. где-то позже будет написано, что такой указатель можно использовать только для сравнений и других арифметических операций, но нельзя разыменовывать (или это станет следствием нескольких пунктов)
0
|
||||
|
285 / 176 / 21
Регистрация: 16.02.2018
Сообщений: 666
|
||||||
| 21.05.2018, 23:11 | ||||||
|
Есть места, типа поведения темплейтов, где всё настолько запутано или недописано, что никто не может точно сказать, какое должно быть поведение при компиляции специально подобранного кода. Тут же случай весьма простой и если для кого-то это не так — то просто значит уровень не тот. Добавлено через 11 минут
int* не является указателем на элемент массива int[50][2], т.к. элемент этого массива это int[2].В массиве int mm[50][2], mm[0] и, например, mm[1] — это два разных объекта-массива int[2]. Получив указатель на элемент первого массива (например, &mm[0][0]), во второй никак арифметикой с этим указателем не попадёшь. Что в C, что в C++.
0
|
||||||
|
|
||
| 23.05.2018, 21:12 | ||
|
А про UB и constexpr - это я понимаю. Но если на этом тесте происходит выдачи ошибки компилятора, то это условно подтверждает, что в этом месте UB. Но который из миллиона всяких UB'ов - неизвестно. Ты утверждаешь, что UB именно этот. Я утверждаю, что нет, потому что этот UB про другое. Потому и написал, что в примере с constexpr'ами, возможно, речь идёт о каком-то другом пункте стандарта
0
|
||
|
285 / 176 / 21
Регистрация: 16.02.2018
Сообщений: 666
|
||
| 23.05.2018, 21:55 | ||
int(*)[2]. Там про сложение числа с любым указателем.Если честно, мне не понятно, что тут может вызывать затруднение, т.к. тут идёт речь про довольно простые вещи: массив, элемент массива, указатель на элемент массива. Указатель int* m был инициализирован выражением &m[0][0]. m это массив int[50][2], m[0] это массив int[2], m[0][0] это первый элемент массива int[2], а &m[0][0] — адрес этого элемента. Следовательно, при прибавлении или вычитании числа к этому указателю нельзя выходить за пределы массива размера 2. Вот и всё. Я не знаю, как ещё понятнее это можно описать.
0
|
||
|
|
|||
| 23.05.2018, 22:34 | |||
|
Стандарт, как и любой юридический документ не читают, а трактуют. У меня одна трактовка (в которой побеждает здравый смысл), у тебя своя трактовка (в которой побеждает юриспруденция, хотя я по прежнему с твоей трактовкой не согласен). Чтобы докопаться до реальной истины, как показывает практика, нужно найти в разных местах стандарты разные утверждения, из которых выстроится чёткая и однозначная трактуемая картина. Мне лень этим заниматься
1
|
|||
|
285 / 176 / 21
Регистрация: 16.02.2018
Сообщений: 666
|
|||||
| 23.05.2018, 22:59 | |||||
|
0
|
|||||
|
|
|||
| 24.05.2018, 14:07 | |||
|
Добавлено через 3 часа 52 минуты Кстати, я ещё понял, почему твой пример с constexpr'ом некорректный (демонстрирует не то) C int mm[50][2]; int *m = &m[0][0]; В качестве подтверждения своей гипотезе ты приводишь тест с constexpr'ом. Но проблема в том, что ты в нём взял слишком вырожденный пример - массив 2x2 (т.е. с одинаковыми рамерностями), и эта симметрия ввела тебя в заблуждение Если же этот пример переписать более культурно (с правильно указанным 2-мерным инициализаторов) и менее симметрично (с неквадратным массивом), то получим такую картину C++ constexpr int a[3][2] = { {1,2}, {3,4}, {5,6} }; constexpr int get_third( int const * first ) { return * ( first + 2 ); } static_assert( get_third( (int const*) &a[0][0] ) == 3, "Wrong number." ); Code $ g++-7.3.0 t.cc -std=c++11 -c t.cc:3:1: error: non-constant condition for static assertion static_assert( get_third( (int const*) &a[0][0] ) == 3, "Wrong number." ); ^~~~~~~~~~~~~ t.cc:3:25: in constexpr expansion of 'get_third((& a[0][0]))' t.cc:3:1: error: array subscript value '2' is outside the bounds of array type 'const int [2]' В соответствии со стандартом к указателю &a[0] можно прибавлять 0, 1 или 2. Ты предположил, что эти же правила касаются и указателя &a[0][0] на основании того, что случилась ошибка. Потому что ты ошибку трактовал как относящуюся именно к этому пункту стандарта. Однако прибавление 2 к такому указателю вызвало проблему. Потому что эта причина, по которой компилятор в этом примере выдаёт ошибку, к данному пункту стандарта не относится, а относится к какому-то другому месту стандарта, т.к. проблему вызвал переход за границу младшего измерения, а не старшего Другими словами, пример с constexpr'ом НЕ годится как аргумент в подтверждение твоей гипотезы
1
|
|||
|
285 / 176 / 21
Регистрация: 16.02.2018
Сообщений: 666
|
||||||
| 24.05.2018, 18:49 | ||||||
{ 1, 2, 3, 4, 5, 6, } — тоже правильный инициализатор для массива 3 на 2.Это наводит на мысль, что весь тред ты спорил сам с собой, а не с тем, что говорю я. Надеюсь, ещё через 3 дня ты поймёшь, почему там, где я говорю, UB.
0
|
||||||
| 24.05.2018, 18:49 | |
|
Помогаю со студенческими работами здесь
20
Как передать в функцию указатель на двухмерный массив? Как можно передать массив по ссылке в функцию? Передать двухмерный массив в функцию
Нужно передать двухмерный динамический массив в функцию Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога
Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
|
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование
. \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json>
Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом.
# Check if. . .
|
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так:
https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347
Основана на STM32F303RBT6.
На борту пять. . .
|
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
|
|
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу,
и светлой Луне.
В мире
покоя нет
и люди
не могут жить в тишине.
А жить им немного лет.
|
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила»
«Время-Деньги»
«Деньги -Пуля»
|
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога
Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
|
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога
Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
|