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

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Ответить
Negent
Сообщения: 5
Зарегистрирован: 20 июн 2014, 00:21

Как я знаю, имя массива и указателя тождественны в С++. Из этого следует, что можно инициализировать указатель, а работать с ним, как с именем массива, добавив индекс (квадратный скобки) или смещение к имени массива и круглые скобки со звёздочкой... Но не в этом суть. Я пробовал ввести передачу в функцию двумерного массива (столбы и строки) - не вышло. Очевидно, что где-то вкралась ошибка.
Вот код:

Код: Выделить всё

#include "stdafx.h"
#include <iostream>

using namespace std;

const int size1 = 3;
const int size2 = 4;
int arr[size1][size2] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
	
void arr_fun (int arr[][size2], int size1);

void main ()
{
	arr_fun (arr[][size2], size1);
	system ("pause");
}
void arr_fun (int arr[][size2], size1)
{
	for (int i=0; i<size1; i++)
	{
		for (int j=0; j<size2; j++)
		{
	cout<<"arr["<<i<<"]: "<<arr[i][j]<<endl;
		}
	}
}
Хотя бы дайте общие понятия по логике передачи адреса двух- и более мерного массива в функцию, а дальше, я сам попробую написать =)
Аватара пользователя
Decoder
Сообщения: 308
Зарегистрирован: 19 фев 2008, 23:11
Откуда: Moscow

Существует несколько способов передачи двумерных массивов: это могут быть двойные указатели, структурированные массивы, представление одномерного массива как двумерного и др.
Поумнеть несложно, куда труднее от дури избавиться.
Аватара пользователя
WinMain
Сообщения: 929
Зарегистрирован: 14 янв 2005, 10:30
Откуда: Москва
Контактная информация:

Вот примерно так это можно реализовать...

Код: Выделить всё

 const int size1 = 3;
 const int size2 = 4;
 int arr[size1][size2] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
 int* arr_ptr[size1] = {arr[0], arr[1], arr[2]};

 void arr_func (int* ptr[], int size);

int main(int argc, char* argv[])
{
	arr_func(arr_ptr, size1);
	return 0;
}

 void arr_func (int* ptr[], int size)
 {
	 for (int i = 0; i < size; i++)
	 {
		 for (int j = 0; j < size2; j++)
		 {
			 int a = ptr[i][j];
			 printf("%d, ", a); 
		 }
		 printf("\n");
	 }
 }
Negent
Сообщения: 5
Зарегистрирован: 20 июн 2014, 00:21

WinMain писал(а):Вот примерно так это можно реализовать...

Код: Выделить всё

 const int size1 = 3;
 const int size2 = 4;
 int arr[size1][size2] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
 int* arr_ptr[size1] = {arr[0], arr[1], arr[2]};

 void arr_func (int* ptr[], int size);

int main(int argc, char* argv[])
{
	arr_func(arr_ptr, size1);
	return 0;
}

 void arr_func (int* ptr[], int size)
 {
	 for (int i = 0; i < size; i++)
	 {
		 for (int j = 0; j < size2; j++)
		 {
			 int a = ptr[i][j];
			 printf("%d, ", a); 
		 }
		 printf("\n");
	 }
 }

Ну вообще-то я не так хотел сформулировать вопрос. Дело в том, что в коде, указанном у меня, массив глобально задан, и поэтому его передавать не надо - можно просто обращаться к элементам массива, как если бы он был доступен всюду. Правильный вопрос такой: если я массив уберу в функцию main (), то как к нему должна обращаться другая функция?

Код: Выделить всё

void main ()
{
const int size1 = 3;
 const int size2 = 4;
 int arr[size1][size2] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
 int* arr_ptr[size1] = {arr[0], arr[1], arr[2]};
...
system ("pause");
}
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

А по-моему WinMain на 100% полностью понял, что ты имел в виду и приведённый им код полностью покрывает твой вопрос. Если не понятно, я добавлю дополнительную фразу, которую не получится уже трактовать никак иначе: при передаче массивов (не важно скольки мерных), все размеры следует передавать отдельными параметрами.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Negent
Сообщения: 5
Зарегистрирован: 20 июн 2014, 00:21

Понятно, спасибо =)

Как ни крутился, всё равно без глобальных переменных обойтись не удалось:

Код: Выделить всё

#include "stdafx.h"
#include <iostream>

using namespace std;

const int size2 = 4;

void show_arr (int arr[][size2], int);

void main ()
{
    static const int size1 = 3;
    int arr[size1][size2] = {{1,2,3,4},{4,5,6,7},{7,8,9,0}};
    show_arr (arr, size1);
    system ("pause");
}
void show_arr (int arr[][size2], int size1)
{
    for (int i=0; i<size1; i++)
    {
        for (int j=0; j<size2; j++)
        {
            cout<<"Array["<<i+1<<"]: "<<arr[i][j]<<endl;
        }
    }
}
Наверное, нужно пересмотреть методику создания самого массива =)
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Если параметр функции объявлен как массив, то указывать в квадратных скобках любые числа бесполезно. Эти числа всё равно будут проигнорированы компилятором, а массив всё равно будет расценен, как указатель соответствующего уровня косвенности. Таким образом, два следующих объявления эквивалентны с точки зрения комилятора:

Код: Выделить всё

void foo(int arr[]);
void foo(int * const arr);
Далее по поводу глобальной переменной. Что мешает передать вторую размерность массива через ещё один параметр?

Код: Выделить всё

#include "stdafx.h"
#include <iostream>

using namespace std;

void show_arr(int arr[][], int, int);

void main ()
{
     static const int size1 = 3;
     static const int size2 = 4;
     int arr[size1][size2] = {{1,2,3,4},{4,5,6,7},{7,8,9,0}};
     show_arr(arr, size1, size2);
     system("pause");
}

void show_arr(int arr[][], int size1, int size2)
{
     for (int i=0; i<size1; i++)
     {
         for (int j=0; j<size2; j++)
         {
             cout<<"Array["<<i+1<<"]: "<<arr[i][j]<<endl;
         }
     }
}
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Ответить