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

Двумерный массив передать через **arr - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.80
Selendis
1 / 1 / 0
Регистрация: 15.02.2011
Сообщений: 43
10.03.2011, 20:05     Двумерный массив передать через **arr #1
Добрый день.
Поискал похожие темы, кое-что нашел, но у меня проблема в том, что мне нужно передать уже созданный двумерный массив int arr[8][8] в функцию с прототипом void f(int **arr)

Передать пустоту f(NULL) и там его создать - это я могу.
А вот сделать так, чтобы такая функция съела arr[8][8] - ну f(arr) в смысле - так, как если бы там был этот самый двумерный массив в прототипе - не получается.

Были предложения о том, чтобы либо иметь void-указатель и привести его явно в функции, либо пользоваться reinterpret_cast<int**>(arr) при вызове - но у меня не получается это сделать, runtime error получаю или просто явно не приводится, т.е. вот эта штука
C++
1
2
3
4
5
        int ar[8][8] = {0};
    int **br;
 
    void **vr;
    vr = (int**) ar;
не работает, а хотелось бы. Может быть, есть смысл какой-нибудь архаичный С-style компиллятор попробовать, который не так бьет за фривольности void*? Сейчас Studio 10.

Суть задания в том, чтобы в функцию void f(int **arr) передать уже созданный массив int arr[8][8].
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
VASSUV
MiThEoN
 Аватар для VASSUV
412 / 278 / 15
Регистрация: 31.10.2009
Сообщений: 403
Записей в блоге: 2
10.03.2011, 21:01     Двумерный массив передать через **arr #2
передавать в функцию не пробовал ссылку на первый элемент?
C++
1
f (&(arr[0][0]));
skaa
Хочу в Исландию
 Аватар для skaa
1024 / 823 / 75
Регистрация: 10.11.2010
Сообщений: 1,626
10.03.2011, 21:10     Двумерный массив передать через **arr #3
А так не подойдёт:
C++
1
f((int **)arr);
?
Selendis
1 / 1 / 0
Регистрация: 15.02.2011
Сообщений: 43
10.03.2011, 21:32  [ТС]     Двумерный массив передать через **arr #4
f(&(arr[0][0])) - несоответствие типов, cannot convert parameter 1 from 'int *' to 'int **'

f((int **)arr) - runtime error, передаваться он как-то передается, но обратиться я к нему в функции не могу ни по **arr, ни по arr[i][j].
VASSUV
MiThEoN
 Аватар для VASSUV
412 / 278 / 15
Регистрация: 31.10.2009
Сообщений: 403
Записей в блоге: 2
10.03.2011, 21:39     Двумерный массив передать через **arr #5
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <conio.h>
#define n 10
#define m 8
void f( int* arr)
{
    for(int i = 0 ; i < n; i++)
    {
        for(int j=0; j<m; j++)
            printf("%d   ",arr[i*m +j]);
        printf("\n");
    }
}
void main()
{
    int arr[n][m] = {   
                                  {1, 2, 3, 4, 5, 6, 7, 8},
                                  {2, 3, 4, 5, 6, 7, 8, 9},
                                  {3, 4, 5, 6, 7, 8, 9, 10},
                                  {4, 5, 6, 7, 8, 9, 10,11},
                                  {5, 6, 7, 8, 9, 10,11,12},
                                  {6, 7, 8, 9, 10,11,12,13},
                                  {7, 8, 9, 10,11,12,13,14},                                  
                                  {8, 9, 10,11,12,13,14,15},
                                  {9, 10,11,12,13,14,15,16},
                                  {10,11,12,13,14,15,16,17}};
    f(&(arr[0][0]));
    getch();
}
Selendis
1 / 1 / 0
Регистрация: 15.02.2011
Сообщений: 43
10.03.2011, 22:09  [ТС]     Двумерный массив передать через **arr #6
VASSUV спасибо, но у меня прототип функции непременно должен быть void f(int **ar), т.е. указатель на указатель.
VASSUV
MiThEoN
 Аватар для VASSUV
412 / 278 / 15
Регистрация: 31.10.2009
Сообщений: 403
Записей в блоге: 2
10.03.2011, 22:56     Двумерный массив передать через **arr #7
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include<conio.h>
#include<stdio.h>    
#define n 10
#define m 8
void f( int** a)
{
    for(int i = 0 ; i < n; i++)
    {
        for(int j=0; j<m; j++)
            printf("%d   ",a[i][j]);
        printf("\n");
    }
}
void main()
{
    int ar[n][m]    = { 
            {1, 2, 3, 4, 5, 6, 7, 8},
            {2, 3, 4, 5, 6, 7, 8, 9},
            {3, 4, 5, 6, 7, 8, 9, 10},
            {4, 5, 6, 7, 8, 9, 10,11},
            {5, 6, 7, 8, 9, 10,11,12},
            {6, 7, 8, 9, 10,11,12,13},
            {7, 8, 9, 10,11,12,13,14},
            {8, 9, 10,11,12,13,14,15},
            {9, 10,11,12,13,14,15,16},
            {10,11,12,13,14,15,16,17}};
    int **arr;
    arr = (int **) malloc(sizeof(int*)*n);
    for(int i = 0; i < n; i++)
    {
        arr[i] = (int *) malloc(sizeof(int)*m);
        arr[i] = &(ar[i][0]);
    }
    f(arr);
    getch();
}
Я думаю нет варианта больше, чем, как создавать динимический массив и только тогда его передавать в функцию!
Selendis
1 / 1 / 0
Регистрация: 15.02.2011
Сообщений: 43
10.03.2011, 23:18  [ТС]     Двумерный массив передать через **arr #8
Спасибо, действительно работает.
Я правда вот так писал:
C++
1
2
3
4
5
         br = new int*[8];
        for(i = 0; i < 8; i++)
        {
            br[i] = new int[8];
        }
В связи с чем вопрос - а где тут сборка мусора - ну банальное освобождение памяти и как его сделать корректно - в вашем случае free конечно же, в моем delete и тоже без идей.

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

И я все еще не оставляю надежды на то, что кто-либо подскажет способ выполнить задачу, имея на руках готовый массив ar[8][8];, возможно через приведения типа пустого указателя или reinterpret_cast.
skaa
Хочу в Исландию
 Аватар для skaa
1024 / 823 / 75
Регистрация: 10.11.2010
Сообщений: 1,626
10.03.2011, 23:44     Двумерный массив передать через **arr #9
По-моему в Микрософте что-то не дописали...
Попробуйте так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void    main()
{
 
    int arr[8][8];
 
    arr[0][0]=9;
    arr[0][1]=8;
    arr[1][0]=7;
    arr[1][1]=6;
//  ...
    f((int **)arr);
}
void    f(int **arr)
{
    int *an;
    int n;
 
    an=(int *)arr;
    n=(int)an[0];
    an[0]=10;
    an[1]=11;
}
, мусор убирать не надо потому что работаем только с указателями и никакой памяти не резервируем.

Добавлено через 10 минут
В этом случае an[N*8+M] указывает на arr[N][M]. Я проверил в VS 2008.
VASSUV
MiThEoN
 Аватар для VASSUV
412 / 278 / 15
Регистрация: 31.10.2009
Сообщений: 403
Записей в блоге: 2
10.03.2011, 23:53     Двумерный массив передать через **arr #10
Цитата Сообщение от skaa Посмотреть сообщение
Я проверил в VS 2008.
Плохо проверял!
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void    f(int **arr)
{
    int     *an;
    an=(int *)arr;
    for(int i = 0; i<3; i++)
    {   
        for(int j=0; j<4; j++)
            printf("%d   ",(int)an[i*3+j]);
        printf("\n"); 
    }
}
void main()
{
    int a[3][4]={{1,2,3,4},{4,3,2,1},{5,5,5,5}};
    f((int**)a);
    getch();
}
Так работает не правильно!
Но так вроде правильно!
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void    f(int **arr)
{
    int     *an;
    for(int i = 0; i<3; i++)
    {   
        an=(int *)(arr+i);
        for(int j=0; j<4; j++)
            printf("%d   ",(int)an[i*3+j]);
        printf("\n"); 
    }
}
void main()
{
    int a[3][4]={{1,2,3,4},{4,3,2,1},{5,5,5,5}};
    f((int**)a);
    getch();
}
Selendis
1 / 1 / 0
Регистрация: 15.02.2011
Сообщений: 43
10.03.2011, 23:55  [ТС]     Двумерный массив передать через **arr #11
skaa Спасибо за вариант, конечно должно работать, напрягает то, что нельзя a[i][j] по человечески - приходится суммированием заниматься.

Я сейчас шаманю на предмет "а вдруг в *.с он будет более адекватно к приведению типов относиться"
a_lebedev
6 / 6 / 0
Регистрация: 05.02.2011
Сообщений: 48
11.03.2011, 00:02     Двумерный массив передать через **arr #12
Создание, передача, удаление массива:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//---------------------------------------------------------------------------
void f(int **arr, int ColCount, int RowCount)
{
    //...
}
//---------------------------------------------------------------------------
int main(int argc, char* argv[])
{
    //...
    int i;
    int **arr = new int* [8];
    for (i = 0; i < 8; i++)
    {
        arr[i] = new int [8];
    }
    f(arr, 8, 8);
    //...
    for (i = 0; i < 8; i++) delete [] arr[i];
    delete [] arr;
    return 0;
}
//---------------------------------------------------------------------------
Selendis
1 / 1 / 0
Регистрация: 15.02.2011
Сообщений: 43
11.03.2011, 00:05  [ТС]     Двумерный массив передать через **arr #13
a_lebedev Пусть массив не динамический, а int arr[8][8]. А в прототипе функции да, int **ar.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.03.2011, 00:56     Двумерный массив передать через **arr
Еще ссылки по теме:

Передать в функцию двумерный массив C++
C++ Как передать двумерный массив функции?
C++ Не могу передать двумерный массив в функцию

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

Или воспользуйтесь поиском по форуму:
a_lebedev
6 / 6 / 0
Регистрация: 05.02.2011
Сообщений: 48
11.03.2011, 00:56     Двумерный массив передать через **arr #14
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//---------------------------------------------------------------------------
void f(int arr[8][8])
{
    //...
}
//---------------------------------------------------------------------------
int main(int argc, char* argv[])
{
    //...
    int arr [8][8];
    f(arr);
    //...
    return 0;
}
//---------------------------------------------------------------------------
Добавлено через 42 минуты
"Если двухмерный массив используется в качестве аргумента функции, то в нее передается только указатель на его первый элемент. Однако при этом НЕОБХОДИМО УКАЗАТЬ, ПО КРАЙНЕЙ МЕРЕ, КОЛИЧЕСТВО СТОЛБЦОВ. (Можно, разумеется, задать и количество строк, но это не обязательно.) Количество столбцов необходимо компилятору для того, чтобы правильно вычислить адрес элемента массива внутри функции, а для этого должна быть известна длина строки."
Г. Шилдт Справочник по С++ 106 страница.
Итого можно еще так:
C++
1
2
3
void f(int arr[][8])
{
}
Или использовать указатель **arr, как было предложено VASSUV
Yandex
Объявления
11.03.2011, 00:56     Двумерный массив передать через **arr
Ответ Создать тему
Опции темы

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