Форум программистов, компьютерный форум CyberForum.ru

Return многомерного массива - C++

Восстановить пароль Регистрация
 
SerjInsane
0 / 0 / 0
Регистрация: 18.10.2012
Сообщений: 30
25.05.2014, 13:57     Return многомерного массива #1
не понимаю как передавать многомерные массивы в c++.
есть массив char arr[50][3][20]
есть два класса.
в первом должен быть метод который будет возвращать массив arr. т.е. что-то вроде:
C++
1
2
3
char getArr() {
    return this->arr;
}
в другом классе будет вызываться сей метод и осуществляться следующая работа:
C++
1
2
3
4
5
6
char arr = class1->getArr();
for(int i=0;i<sizeof(arr);i++) {
    System::String ^ one = gcnew System::String(arr[i][1]);
    System::String ^ two = gcnew System::String(arr[i][2]);
    System::String ^ three = gcnew System::String(arr[i][3]);
}
З.Ы. если это очень геморно, то можно разделить arr на 3 отдельных массива: arr1[50][20], arr2[50][20], arr3[50][20].
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Чумаков Антон
85 / 67 / 17
Регистрация: 07.03.2011
Сообщений: 168
25.05.2014, 15:55     Return многомерного массива #2
Так передайте ссылку на массив.

Добавлено через 2 минуты
Точнее, указатель
C++
1
2
3
4
void getArr(char*)
{
    /* Что-то делает */
}
Добавлено через 8 минут
Что-то бессмысленное я написал ранее.
Может быть, лучше обойтись без копирования массива и работать в методе второго класса непосредственно с исходным массивом? Через указатели.
SerjInsane
0 / 0 / 0
Регистрация: 18.10.2012
Сообщений: 30
27.05.2014, 19:57  [ТС]     Return многомерного массива #3
Что-то я все равно не понимаю.
inst_mefi
22 / 25 / 5
Регистрация: 10.10.2013
Сообщений: 165
27.05.2014, 20:21     Return многомерного массива #4
C++
1
2
3
4
5
6
7
8
9
10
11
12
//Объявляем массив внутри класса статическим
static char*** arr;
 
 
//И 
char*** GetArr()
{
return this->arr;
}
 
//И в основной функции 
char*** arr=class1->GetArr();
Добавлено через 1 минуту
Только это работает, если у вас всего один объект этого класса.
SerjInsane
0 / 0 / 0
Регистрация: 18.10.2012
Сообщений: 30
27.05.2014, 21:27  [ТС]     Return многомерного массива #5
Подскажите пожалуйста кто-нибудь как реализовать задуманное не через указатели? Массив должен быть именно char arr[50][3][20] либо char arr1[50][20], arr2[50][20], arr3[50][20].
inst_mefi
22 / 25 / 5
Регистрация: 10.10.2013
Сообщений: 165
28.05.2014, 00:46     Return многомерного массива #6
Во-первых, arr[50][2][30] представляет из себя(как бы ты это не объявлял, хоть так, хоть указателем) следующую последовательность действий:
1)Взять указатель arr
2)Перейти на 50 элемент массива, на который указывает arr
3)Перейти на 2 элемент массива, на который указывает arr[50]
4)Перейти на 30 элемент массива, на который указывает arr[50][2](именно в этот момент заканчиваются указатели и начинаются переменные)
Во-вторых, если ты все-таки очень принципиальный, то можешь сделать функцию, которая принимает твой массив и копирует в него данные из массива в классе.
Юрий77
0 / 0 / 0
Регистрация: 23.04.2015
Сообщений: 2
23.04.2015, 22:09     Return многомерного массива #7
Ну хоть кто нибудь сказал как возвращать многомерный массив,
Ну сколько можно мучить эту тему, замучили со своими указателями, инициализациями...
Вот как правильно возвращать многомерный массив на примере двумерного:

C++
1
2
3
4
5
6
7
8
9
10
11
12
int (*getArr())[10]
{
   static int arr[10][10];
   return arr;
}
int main()
{
   int (*arr2)[10];
   arr2=getArr();
   //example of use
   cout << arr2[1][5];
}
Вот и вся мудрость, и не надо говорить, что массивы из функции не возвращаются.

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

Самый первых элемент массива указывает на начало сплошного потока данных, например int.
Число элементов массива будет равна произведению размерностей массива друг на друга.
Размерности массива указываются только для компилятора и Вашего удобства.
Когда Вы инициализируете размерности для массива, то компилятор запоминает эти данные.
Далее, при попытке доступа к данным, компилятор отсчитывает от самого начала массива
число равное смещению на примере покажу:
int arr[measure1][measure2][measure3], допустим cout << arr[1][2][3];

смещение данных будет: 1 * measure2 * measure3 + 2 * measure3 + 3;
можете убедиться :
получаем указатель на первый элемент int* arrPtr = &arr[0][0][0];
прибавляем к нему вычисленное смещение arrPtr+=1 * measure2 * measure3 + 2 * measure3 + 3;
заносим в массив данные arr[1][2][3]=5;
и получаем значение из указателя, полученного выше cout<< *arrPtr;
Таким образом все указатели идут в массиве один за другим без разбиения.
На самом нижнем уровне массивы и не существуют вовсе.
daslex
1084 / 494 / 101
Регистрация: 02.08.2011
Сообщений: 2,408
24.04.2015, 07:41     Return многомерного массива #8
Массив как именно массив никак.
Так или иначе возвращается только указатель.
Не вводите в заблуждение других пользователей. В качестве данных указатели вполне себе умеют жить внутри массива.
Массив бы возвращался если return arr[10][10]
А у вас возвращается исключительно указатель arr, который указывает на начало массива [10][10].
gru74ik
Модератор
 Аватар для gru74ik
3121 / 1347 / 167
Регистрация: 20.02.2013
Сообщений: 3,852
Записей в блоге: 17
24.04.2015, 09:17     Return многомерного массива #9
Цитата Сообщение от daslex Посмотреть сообщение
Массив как именно массив никак.
Если только он не std::vector (или ещё какой-нибудь класс-контейнер).
Юрий77
0 / 0 / 0
Регистрация: 23.04.2015
Сообщений: 2
30.04.2015, 11:52     Return многомерного массива #10
daslex
Да, безусловно, массив автоматически не возвращается и не копируется при передачах в функции. Может я не правильно выразился. Я постарался показать как правильно возвращать указатель на двумерный массив, чтобы компилятор не сильно ругался.
Когда Вас спрашивают: - "А как вернуть массив?", тогда у Вас интересуются именно как вернуть указатель. Да может большинство не артикулируют об этом по-тому, что не до конца понимают сути, но имеют именно этот вопрос. Я просто возмущен огромным количеством пустословия на эту тему, чем впрочем сейчас занимаемся мы. Можете, конечно, сказать - "я не отвечаю на неправильные вопросы, каков вопрос - таков ответ". Но, иногда задать правильный вопрос тоже в некотором смысле мастерство, которым зачастую новички не обладают......
ЗЫ.
Без обид - А Вы, daslex, сами то знали, как правильно????
Да, кстати, если возвращать "daslex-"Массив бы возвращался если return arr[10][10]" Этот массив не имеет смысла возвращать, т.к. после возврата из функции указатель на массив перестанет быть действительным. Таким образом нельзя массиву придать, например статичность, или записать в него данные - бесполезная пустышка.
Вот Вам задача - инициализируйте вот такое объявление - const int const arr[10000][10000] в начале файла, допустим нулями. - не прибегая к ручной инициализации типа const int const arr[2][2]={{0,0},{0,0}}; был бы благодарен - сам не знаю как.
DrOffset
6458 / 3832 / 885
Регистрация: 30.01.2014
Сообщений: 6,627
30.04.2015, 12:26     Return многомерного массива #11
Цитата Сообщение от Юрий77 Посмотреть сообщение
инициализируйте вот такое объявление - const int const arr[10000][10000] в начале файла, допустим нулями
Если именно нулями, то просто достаточного этого:
C++
1
    const int const arr[10000][10000] = {};
Добавлено через 15 минут
Цитата Сообщение от Юрий77 Посмотреть сообщение
Этот массив не имеет смысла возвращать, т.к. после возврата из функции указатель на массив перестанет быть действительным.
Для обращения с массивом как с объектом, т.е. целиком, а не через каст к указателю, существуют специальные средства. Например класс std::array.
С ним твой пример будет выглядеть так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
std::array<std::array<int, 10>, 10> getArr()
{
   std::array<std::array<int, 10>, 10> arr = {};
 
   return arr;
}
 
int main()
{
   std::array<std::array<int, 10>, 10> arr2 = getArr();
 
   std::cout << arr2[1][5];
}
По факту, std::array - это простая обертка над обычным массивом, кроме этого самого массива в ней других данных нет и сложной подкапотной работы тоже (как, например, есть в векторе), но она позволяет навесить "первоклассность" (устал давать уже эту ссылку) на объект масива и использовать его везде, как обычную переменную.

Цитата Сообщение от SerjInsane Посмотреть сообщение
Подскажите пожалуйста кто-нибудь как реализовать задуманное не через указатели?
Собственно это был ответ на этот вопрос.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
30.04.2015, 13:42     Return многомерного массива
Еще ссылки по теме:

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

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

Или воспользуйтесь поиском по форуму:
daslex
1084 / 494 / 101
Регистрация: 02.08.2011
Сообщений: 2,408
30.04.2015, 13:42     Return многомерного массива #12
Юрий77, какое пустословие в том, что
а) Массив нельзя присвоить массиву, следовательно возврат его из функции несет слишком мало смысла и годился бы скорее всего только для инициализации массива.
б) Массив никогда не возвращается из функции
в) Надо называть вещи своими именами.

Цитата Сообщение от Юрий77 Посмотреть сообщение
А Вы, daslex, сами то знали, как правильно????
Было время - не знал. Почитал книжки, узнал. Об этом во всех абсолютно книжках пишут (хороших). Узнал, что нельзя.

Добавлено через 6 минут
И, да. Когда говорят "Указатель", сразу приходит непонимание. Тут ничего не поделаешь. Но только указатели решают этот вопрос. (либо вектор, либо обертки всякие).

Добавлено через 8 минут
Даже просто объявить функцию, которая возвращает массив нельзя. Получим ошибку: "Функция объявлена как функция возвращающая массив". Ошибка такая вот

С++11
C++
1
2
3
int foo()[5]{
    return {1,2,3,4,5}; //Вообще так можно, но только если не массив, а структура или класс
}
С++11 корректно
C++
1
2
3
4
5
6
7
struct A{
    int Arr[5];
};
 
A foo(){
    return {{1,2,3,4,5}};
}
Но структуры можно присваивать структурам, в отличии от массивов, поэтому это имеет смысл.

Добавлено через 33 минуты
Ну и собственно присваивать массив в массив нельзя, поэтому

C++
1
2
3
4
int main(){
   int Arr[5];
  for (int i=0;i<5;i++) Arr[i]=foo().Arr[i];  //Не очень эффективно, правда?
}
Добавлено через 3 минуты
Ну или
C++
1
2
 int Arr[5];
      memcpy(Arr,foo().Arr,5*sizeof(int));
все равно эффективности нет.
Yandex
Объявления
30.04.2015, 13:42     Return многомерного массива
Ответ Создать тему
Опции темы

Текущее время: 06:38. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru