Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.89/47: Рейтинг темы: голосов - 47, средняя оценка - 4.89
117 / 121 / 42
Регистрация: 25.08.2012
Сообщений: 1,294

Передача двумерных массивов и указателей в функцию

15.08.2015, 10:26. Показов 9733. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам

Не по теме:

Warning: если про это уже было, можете удалить это сообщение


Передача двумерного массива функции

Уже в который раз натыкаюсь на тему об ошибке передачи двумерного массива в функцию (либо при преобразовании типов, либо при индексации элементов). Так вот, сейчас я, фактически, перепишу страницу из "Языка программирования С++" от Сами-Знаете-Кого, так что если вы действительно хотите разобраться с фокусами С++, достаньте и прочтите эту книгу.

Когда вы пишите так:
C++
1
int something(int** array, const int row, const int col)
Компилятор ожидает, что вы передадите указатель на указатель, но (во всяком случае у меня, а я пользуюсь VS 2013) передавая двумерный массив так:
C++
1
something(array, r, c);
Или так:
C++
1
something(&array[0], ...);
Компилятор откажется делать свою работу, в первом случае жалуясь на фактический аргумент типа int[3][3] (допустим, у нас матрица 3-го порядка), а во втором случае — на int(*)[3], которые пытаются выставить за int**.

Такое объявление тоже не сработает:
C++
1
int some(int array[][], ...);
А вот такие вполне сработают:
C++
1
2
3
int some(int array[][3], int row);
//   или так
int some(int array[3][3]);
Но ведь тогда нужно знать размер массива (или хотя бы всех кроме первой размерностей) до компиляции программы!

В общем, решением является следующее:
C++
1
2
3
4
5
6
7
8
9
10
11
12
int some(int* array, const int row, const int col)
{
   ...
   array[i * col + j] = ... ;    // работает.
}
 
int main()
{
   ...
   int array[3][3];
   some(&array[0][0], 3, 3);
}
Теперь пара-тройка замечаний:

1. В ранних компиляторах и в языке Си передавать массивы через двойной указатель можно, но ошибку времени исполнения схватить можно запросто (из-за access violation, скорее всего).
2. А вообще вы пользуетесь языком С++, в котором есть прекрасный класс vector<>, так что если вы пишите обычную программу (у которой нет серьезных ограничений по памяти/времени), пользуйтесь им.
3. Массивы строк (char* strs[]) передавать через двойной указатель можно, поскольку там в качестве последнего элемента выступает '\0', а все функции обработки строк стандартной библиотеки обрабатывают строки до этого символа.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
15.08.2015, 10:26
Ответы с готовыми решениями:

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

Передача двумерных массивов в функцию
мне дано такое задание: &quot;Написать функцию сглаживания заданной во входном параметре матрицы. Операция сглаживания матрицы дает новую...

Передача двумерных массивов в функцию
Как передать значения двух матриц из одной функции в другую? Объясните, пожалуйста. #include &quot;pch.h&quot; #include...

11
Неэпический
 Аватар для Croessmah
18146 / 10730 / 2066
Регистрация: 27.09.2012
Сообщений: 27,029
Записей в блоге: 1
15.08.2015, 10:42
tnk500,
C++
1
2
3
4
5
6
7
8
9
10
11
12
template < typename T , size_t N , size_t M >
int some(T (&array)[N][M], const int row, const int col)
{
    //тадам
}
 
int main()
{
   ...
   int array[3][8];
   some(array, 3, 3);
}
1
117 / 121 / 42
Регистрация: 25.08.2012
Сообщений: 1,294
15.08.2015, 10:55  [ТС]

Не по теме:

Croessmah, согласен, шаблоны тоже решение. Но я писал для самых-самых зеленых, которые с шаблонами, может, и незнакомы. К тому же сомневаюсь, что человек, знающий о шаблонах, не будет знать правил передачи двумерных массивов.



И разумеется, я забыл о динамических массивах. В них передача через двойной (в зависимости от размерности) указатель является по умолчанию.
0
Неэпический
 Аватар для Croessmah
18146 / 10730 / 2066
Регистрация: 27.09.2012
Сообщений: 27,029
Записей в блоге: 1
15.08.2015, 10:58
Цитата Сообщение от tnk500 Посмотреть сообщение
И разумеется, я забыл о динамических массивах.
Вы забыли не об этом, а о том, что МАССИВ ЭТО НЕ УКАЗАТЕЛЬ!
1
Эксперт С++
 Аватар для Mr.X
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
15.08.2015, 10:59
Цитата Сообщение от tnk500 Посмотреть сообщение
Уже в который раз натыкаюсь на тему об ошибке передачи двумерного массива
Страуструп-то и одномерные в С++ не рекомендует использовать. Не понимаю этой любви к этому недотипу, да еще из другого языка, да еще и наворачиванию многомерных.
0
Неэпический
 Аватар для Croessmah
18146 / 10730 / 2066
Регистрация: 27.09.2012
Сообщений: 27,029
Записей в блоге: 1
15.08.2015, 11:00
Цитата Сообщение от Mr.X Посмотреть сообщение
Не понимаю этой любви к этому недотипу, да еще из другого языка
обратная совместимость и т.д.
0
117 / 121 / 42
Регистрация: 25.08.2012
Сообщений: 1,294
15.08.2015, 11:13  [ТС]

Не по теме:

Mr.X, см. в конец того сообщения. И все же они где-то да нужны.


Croessmah, конечно, иначе и ошибок, мною описанных, не было бы. И операция new возвращает указатель на выделенный элемент(-ы) в куче. Честно говоря, был бы благодарен, если бы вы пояснили смысл вашего высказывания
0
Неэпический
 Аватар для Croessmah
18146 / 10730 / 2066
Регистрация: 27.09.2012
Сообщений: 27,029
Записей в блоге: 1
15.08.2015, 11:30
Цитата Сообщение от tnk500 Посмотреть сообщение
если бы вы пояснили смысл вашего высказывания
C++
1
2
3
4
   int a[3] = { 5 , 9 , 4 };
   int (*p)[3] = &a ; //<- указатель на массив
   for ( int & e : *p )
      std::cout << e << ' ' ;
0
117 / 121 / 42
Регистрация: 25.08.2012
Сообщений: 1,294
15.08.2015, 11:52  [ТС]
Croessmah, простите, но я где-то говорил, что массивы и указатели — одно и то же?) Я писал, что при передаче через обычный (общий) двойной указатель (int**) двойного массива выйдет ошибка компиляции, что чуть намекает на мою позицию. Ваш же пример специфицирует тип указателя до указателя на массив с тремя элементами, что вполне законно для целей указания на массив фиксированной длины. Этот же указатель можно передать функции, ожидающей указатель на массив такой длины.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
15.08.2015, 16:51
Цитата Сообщение от tnk500 Посмотреть сообщение
я где-то говорил, что массивы и указатели — одно и то же?
речь не об этом.
речь о том, что когда заходит речь о передаче массивов,
то всегда заходит речь об указателях.

в итоге в неокрепших деццких мозгах формируется каша.

например такая:
C++
1
2
3
4
5
6
7
int a[10]={};
 
int* p = new int[10];
 
// --- ну и в чем тогда разница?
p[2] = 3; 
a[2] = 3;
а потом они вырастают,
но продолжают наивно верить в "динамические массивы",
подразумевая при этом указатель.
0
117 / 121 / 42
Регистрация: 25.08.2012
Сообщений: 1,294
15.08.2015, 17:08  [ТС]
hoggy, но ведь не будете же вы называть динамический массив указателем на область памяти, выделенную во время исполнения? Да и называют скорее всего по привычке, в других распространенных ЯП динамический массив массивом и называется, вот и здесь указатель на дин. память дин. массивом и называют. А на что шарперам/явистам тонкости в типизации статических (обычных, не обязательно со словом static) и "динамических" массивов? Исправят параметризацию однажды, и забудут об этом.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
15.08.2015, 17:53
Цитата Сообщение от tnk500 Посмотреть сообщение
но ведь не будете же вы называть динамический массив указателем на область памяти, выделенную во время исполнения?
я - нет.

но многие (особенно новички), в том числе, на этом форуме - называют.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
15.08.2015, 17:53
Помогаю со студенческими работами здесь

Составить программу на языке C++ для обработки двумерных массивов с использованием указателей
Составить программу на языке C++ для обработки двумерных массивов с использованием указателей. Очень срочно. Завтра экзамен.

Составить программу на языке C++ для обработки двумерных массивов с использованием указателей
Дана матрица порядка n. Найти в последнем столбце max и min. Если в матрице есть нули, то заменить их суммой max и min последнего столбца. ...

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

Какие есть виды массивов (кроме одномерных, двумерных и двумерных ступенчатых массивов)?
Какие есть виды массивов (кроме одномерных, двумерных и двумерных ступенчатых массивов)? И почему такая вот запись является...

Передача массивов указателей в качестве параметров функции
Доброго времени суток, не компилится данный код. Ошибка возникает в функции deal(deck, suit, face);. Код полностью скомпипастил из...


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru