Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > передача функциям многомерных массивов


Автор: ShadowC 21.9.2011, 22:42
собственно вот в чем возник вопрос
что бы передать обычный массив мы поступаем так:
Код

modif(x,6);

это как известно передача по ссылке,
Код

modife(x[5]);

это соответвенно передача по значению,все это для обычных массивов....
Код

modif(x);

вот так выглядит передача полного многомерного массива функции

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

Код

const int z=2;
const int y=2;
int x[z][y]={{78,65},{92,73}};
modif(x[1],y);

Автор: mes 21.9.2011, 23:38
Цитата(ShadowC @  21.9.2011,  21:42 Найти цитируемый пост)
это как известно передача по ссылке,

нет.. такие выводы по предоставленым фрагментам кода сделать нельзя.. как будут передаваться  параметры зависит от того как объявлена функция.. а объявление Вы не привели..

Автор: ShadowC 22.9.2011, 07:00
Цитата(mes @ 21.9.2011,  23:38)
Цитата(ShadowC @  21.9.2011,  21:42 Найти цитируемый пост)
это как известно передача по ссылке,

нет.. такие выводы по предоставленым фрагментам кода сделать нельзя.. как будут передаваться  параметры зависит от того как объявлена функция.. а объявление Вы не привели..

функция лишь принимает то что мы ей передаем,например
Код

modif(x,6);

соответственно функция выглядит так
Код

int modif(int x[],int y)
{}

заголовок функции лишь покажет разрешу ли я модифицировать массив в его исходных ячейках,тоесть если захочу запретить,заголовок будет выглядить так
Код

int modif(const int x[],int y)
{}

если ты знаешь другие способы определить принимающую аргумент функцию,то поделись пожалуйста

Автор: spyswamp 22.9.2011, 09:03
ShadowC, 

Код

int modif(const int ** x, int y) {}


не подходит тебе? Ну, и размер отдавать. Хотя была в C функция, с  помощью которой можно было определять размеры (длину) таких структур. Не помню название, но в стандартных заголовках есть.

Автор: newbee 22.9.2011, 09:22
Цитата(ShadowC @  21.9.2011,  23:42 Найти цитируемый пост)
а вопрос вот в чем заключается,как расшифровать такую передачу многомерного массива.
В функцию передается массив {92,73} и значение y=2.

Цитата(spyswamp @  22.9.2011,  10:03 Найти цитируемый пост)
const int ** x
Двумерный массив никак не связан с указателем на указатель.

Код

void foo(int *arr,int w,int h){
 for(int i=0;i<w;i++){
  for(int j=0;j<h;j++)
   printf("%d ",arr[i*h+j]);
  printf("\n");}}

int main(){
 int a[2][3]={{1,2,3},{4,5,6}};
 foo(&a[0][0],2,3);
 return 0;}

Еще можно при объявлении функции явно указывать, что передается массив:
Код

void foo(int arr[42][]);


Добавлено через 2 минуты и 39 секунд
Цитата(spyswamp @  22.9.2011,  10:03 Найти цитируемый пост)
Хотя была в C функция, с  помощью которой можно было определять размеры (длину) таких структур.
Не было.

Цитата(spyswamp @  22.9.2011,  10:03 Найти цитируемый пост)
Не помню название, но в стандартных заголовках есть.
Во всяком случае в стандартной библиотеке.

Автор: maydjin 22.9.2011, 09:27
Во-первых, учи матчасть и не заявляй столь авторитетно о том, что не до конца понимаешь(ссылки тут ни к лесу ни к огороду).
Во-вторых в 1 примере кода у тебя передаеться указатель на 1 элемент массива, а во втором отдельный элемент массива, что при приведенном тобой прототипе должно вызвать ошибку компиляции, если конечно, в массиве не храняться массивы того же типа.

В с++ массивы представляються указателем на первый элемент, т.е:
Код

int * p=0;//потенциально массив
int array[42];//массив с заранее заданным размером
p=array;//array всего лишь указатель на первый элемент p и array теперь эквивалентны

void someFunc(int * array,...);// функция принимающая первым параметром одномерный массив
//элементов типа int эквивалентно void someFunc(int [],...);


Т.к. масив указатель на первый элемент, двумерный массив - массив указателей на 1-ые элементы массива т.е:
Код

int ** p=0;//потенциально указатель на указатель, указывающий на 1 элемент 1 массива
int array[5][5];//...
p=array;//
void someFunc(int **p,...)//функция принимающая двумерный массив

Да, и в-третьих если всё это для самообучения то дерзай, а если с какой то практической целью, то http://www.cplusplus.com/reference/stl/.

Автор: ShadowC 22.9.2011, 09:33
Цитата(spyswamp @ 22.9.2011,  09:03)
ShadowC, 

Код

int modif(const int ** x, int y) {}


не подходит тебе? Ну, и размер отдавать. Хотя была в C функция, с  помощью которой можно было определять размеры (длину) таких структур. Не помню название, но в стандартных заголовках есть.

вот это тот отрезок кода.
Код

const int z=2;
const int y=2;
int x[z][y]={{78,65},{92,73}};
modif(x[1],y);
int modif(const int x[],const int y)
{}

я знаю что такой вызов передает 1 строчку массива,но как это работает я не понимаю...

Добавлено через 1 минуту и 40 секунд
Цитата(newbee @ 22.9.2011,  09:22)

Цитата(spyswamp @  22.9.2011,  10:03 Найти цитируемый пост)
const int ** x
Двумерный массив никак не связан с указателем на указатель.

вот это не понял

Добавлено через 4 минуты и 7 секунд
Цитата(newbee @ 22.9.2011,  09:22)
Цитата(ShadowC @  21.9.2011,  23:42 Найти цитируемый пост)
а вопрос вот в чем заключается,как расшифровать такую передачу многомерного массива.
В функцию передается массив {92,73} и значение y=2.


вопрос заключается в том как это дело работает

Автор: newbee 22.9.2011, 09:38
Цитата(maydjin @  22.9.2011,  10:27 Найти цитируемый пост)
Т.к. масив указатель на первый элемент, двумерный массив - массив указателей на 1-ые элементы массива т.е:
Люди, ну когда же вы начнете думать? Никакими указателями массивы не "представляются", они могут быть приведены к ним. Массив - это линейный кусок данных. Двумерный, да хоть N-мерный - тоже линейный. Все, что меняется, - это алгоритм вычисления данных, соответствующих индексу.

Цитата(newbee @  22.9.2011,  10:22 Найти цитируемый пост)
void foo(int arr[42][]);

Тут я наврала. int arr[2][3] нужно указывать (первый индекс можно опустить и передавать как еще один аргумент).

Добавлено @ 09:44
Цитата(ShadowC @  22.9.2011,  10:33 Найти цитируемый пост)
вопрос заключается в том как это дело работает
Передается указатель на первый элемент массива {92,73}.

Добавлено @ 09:47
Цитата(ShadowC @  22.9.2011,  10:33 Найти цитируемый пост)
вот это не понял
Массив любой мерности можно привести к указателю на его первый элемент и далее по известным смещениям (индексам) получить доступ к любым данным в этом массиве. Если с некоторой натяжкой еще можно сказать, что массив является указателем, то гооворить о том, что двумерный массив является указателм на указатель, неверно.

Автор: maydjin 22.9.2011, 09:54
Не то что хотел бы оспорить, но разве:
Цитата

Люди, ну когда же вы начнете думать? Никакими указателями массивы не "представляются", они могут быть приведены к ним. Массив - это линейный кусок данных. Двумерный, да хоть N-мерный - тоже линейный. Все, что меняется, - это алгоритм вычисления данных, соответствующих индексу.

хоть как то опровергает то , что переменные через которые мы обращаемся к массиву, на сколько я знаю, всегда являются указателями? И память то естественно линейна для любых структур данных, т.к. в конечном итоге она линейна на уровне железок. И в c++ "двумерный" массив является всего лишь массивом указателей, и даже не кем не гарантированно, что указателей именно на массивы и именно на массивы одного типа или размера, за исключением частного случая когда размерности задаються на этапе компиляции.

P.S. многомерных массивов в c++ кстати вообще не существует  smile .

Автор: newbee 22.9.2011, 10:00
Цитата(maydjin @  22.9.2011,  10:54 Найти цитируемый пост)
переменные через которые мы обращаемся к массиву, на сколько я знаю, всегда являются указателями?
int a[42]. Переменная a не является указателем. Она является массивом. то есть на стеке выделяется место под 42 инта и ни бита под какой-то сферический указатель.

Цитата(maydjin @  22.9.2011,  10:54 Найти цитируемый пост)
P.S. многомерных массивов в c++ кстати вообще не существует
Ну это как посмотреть. int a[2][3]..[128] вполне можно считать многомерным массивом, vector<vector... <int>...> - тоже.

Автор: ShadowC 22.9.2011, 10:05
почему тогда такого рода передача функции 1 строки работает,а вывод одной строки не работает?

Код

cout<<x[1]<<endl;

вызовет ошибку

Автор: newbee 22.9.2011, 10:05
Цитата(maydjin @  22.9.2011,  10:54 Найти цитируемый пост)
 И в c++ "двумерный" массив является всего лишь массивом указателей
:facepalm

Добавлено через 1 минуту и 29 секунд
ShadowC, давай код целиком, мы не телепаты.

Автор: ShadowC 22.9.2011, 10:16
Цитата(newbee @ 22.9.2011,  10:05)
Цитата(maydjin @  22.9.2011,  10:54 Найти цитируемый пост)
 И в c++ "двумерный" массив является всего лишь массивом указателей
:facepalm

Добавлено @ 10:07
ShadowC, давай код целиком, мы не телепаты.

ты уверен что этого хочешь? там код на 200+ строчек

это пример из книги дейтлов,там лишь сказано,что многомерный массив может быть представлен одномерными,но как это делается не сказано

Автор: maydjin 22.9.2011, 10:41
Мде действительно facepalm. Указатель можно представить как массив всегда, обратное не верно.
Т.С. слушай newbee.

Автор: spyswamp 24.9.2011, 18:58
newbee, про определение размеров - это я вспомнил какие-то свои давние эксперименты. Сейчас слегка погуглив, нашел пару вещей:
http://msdn.microsoft.com/en-us/library/z2s077bc(VS.80).aspx
http://developer.apple.com/library/mac/#documentation/Darwin/Reference/Manpages/man3/malloc_size.3.html
Соответственно, это нестандартные вещи, но имеют место быть. Хотя, раз не стандартные, то можно смело на них забить и забыть. Моя неправда. smile

Далее, я и не говорил про то, что многомерный массив и "указатель на указатель на..." (нужное количество вставить) - это одно и то же. Я просто спросил, чем не подходит такой вариант. Кстати, там зря я const плюхнул, т.к. из названия функции modif() можно сделать некие выводы. smile Поэтому прошу заранее мне не присваивать мыслей, которых в голове не наблюдалось. ;)

Личное мнение: при динамическом выделении памяти вряд ли кто-то будет при передаче аргументов заморачиваться со скобочками и т.п. Проще (и очевиднее при чтении кода) когда работа с массивом идет через указатель. Остальное годится сугубо в академических целях для понимания механизма хранения и передачи информации (массив). Сам использую контейнеры вместо низкоуровневых структур.

А так, да, с точки зрения хранения данных в памяти, нет никакой "многомерности". smile

ShadowC, вот нашел еще тебе кой-чего почитать по этому поводу (человек, на мой взгляд, доступно написал, чего повторяться): http://www.rsdn.ru/forum/cpp/443690.1.aspx

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)