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

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

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

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

Не по теме:

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
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
15.08.2015, 10:26
Ответы с готовыми решениями:

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

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

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

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

11
Неэпический
18109 / 10696 / 2062
Регистрация: 27.09.2012
Сообщений: 26,929
Записей в блоге: 1
15.08.2015, 10:42 2
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  [ТС] 3

Не по теме:

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



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

Не по теме:

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


Croessmah, конечно, иначе и ошибок, мною описанных, не было бы. И операция new возвращает указатель на выделенный элемент(-ы) в куче. Честно говоря, был бы благодарен, если бы вы пояснили смысл вашего высказывания
0
Неэпический
18109 / 10696 / 2062
Регистрация: 27.09.2012
Сообщений: 26,929
Записей в блоге: 1
15.08.2015, 11:30 8
Цитата Сообщение от 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  [ТС] 9
Croessmah, простите, но я где-то говорил, что массивы и указатели — одно и то же?) Я писал, что при передаче через обычный (общий) двойной указатель (int**) двойного массива выйдет ошибка компиляции, что чуть намекает на мою позицию. Ваш же пример специфицирует тип указателя до указателя на массив с тремя элементами, что вполне законно для целей указания на массив фиксированной длины. Этот же указатель можно передать функции, ожидающей указатель на массив такой длины.
0
Эксперт С++
8972 / 4318 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
15.08.2015, 16:51 10
Цитата Сообщение от 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  [ТС] 11
hoggy, но ведь не будете же вы называть динамический массив указателем на область памяти, выделенную во время исполнения? Да и называют скорее всего по привычке, в других распространенных ЯП динамический массив массивом и называется, вот и здесь указатель на дин. память дин. массивом и называют. А на что шарперам/явистам тонкости в типизации статических (обычных, не обязательно со словом static) и "динамических" массивов? Исправят параметризацию однажды, и забудут об этом.
0
Эксперт С++
8972 / 4318 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
15.08.2015, 17:53 12
Цитата Сообщение от tnk500 Посмотреть сообщение
но ведь не будете же вы называть динамический массив указателем на область памяти, выделенную во время исполнения?
я - нет.

но многие (особенно новички), в том числе, на этом форуме - называют.
0
15.08.2015, 17:53
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
15.08.2015, 17:53
Помогаю со студенческими работами здесь

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru