Форум программистов, компьютерный форум, киберфорум
Наши страницы
C для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.58/12: Рейтинг темы: голосов - 12, средняя оценка - 4.58
luck
0 / 0 / 0
Регистрация: 06.07.2012
Сообщений: 63
1

Как правильно передавать двумерный массив в функцию

06.07.2012, 16:02. Просмотров 2384. Ответов 10
Метки нет (Все метки)

Компилятор Borland Builder C++ 6
Получил ошибку в основной программе, создал идентичную тестовую, привожу код.
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
#include <math.h>
//--------------------------
 void func (double **a, int i, int j)
  {
   for (;i<100;i++)
    for (;j<100;j++)
     a[i][j]=101.15;
  }
main()
 {
  double a[100][100];
  int i = 0;
  int j = 0;
  func(a,i,j);
  getch();
 }
Так и не понял из многочисленных пояснений, как правильно передавать двумерный массив в функцию.
Ошибка в a[i][j]=101.15; - Access violation at address ... Write of address ...
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.07.2012, 16:02
Ответы с готовыми решениями:

Как правильно передавать динамический двухмерный массив
#include &quot;stdafx.h&quot; #include &lt;stdio.h&gt; #include &lt;conio.h&gt; #include &lt;stdlib.h&gt; #include...

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

Как правильно выделить память под двумерный динамический массив
подскажите как правильно выделить память под двумерный динамический массив?

Как правильно объявить двумерный динамический массив через malloc
Подскажите как правильно объявить двумерный динамический массив через malloc типа инт размером...

Как передать двумерный массив в функцию?
void func(float *mas, int x, int y) { .. for (i=0; i&lt;10; i++) printf (&quot;%d&quot;,mas); } ...

10
Evg
Эксперт CАвтор FAQ
19638 / 7330 / 551
Регистрация: 30.03.2009
Сообщений: 20,508
Записей в блоге: 30
06.07.2012, 17:07 2
"double **a" заменить на "double a[100][100]"

Ещё для интереса почитай тему Функции, передача массива в качестве параметра

Добавлено через 49 секунд
Правда у тебя всё равно будет косячить, т.к. во вложенном цикле у тебя нет обнуления переменной j и в конце-концов ты выскочишь за границу массива

Добавлено через 1 минуту
А не... выхода за границу не будет, но полноценной инициализации массива тоже не будет (проинциализируются только первые 100 элементов). Ну это я на всякий случай
0
luck
0 / 0 / 0
Регистрация: 06.07.2012
Сообщений: 63
07.07.2012, 00:23  [ТС] 3
Я забыл уточнить это в коде, но я так понимаю, при передаче double a[100][100] в main'е не будет изменено значение массива a, что мне требуется.
0
Evg
Эксперт CАвтор FAQ
19638 / 7330 / 551
Регистрация: 30.03.2009
Сообщений: 20,508
Записей в блоге: 30
07.07.2012, 00:33 4
Передать массив как таковой нельзя (уж так устроен язык Си). Такая форма записи всё равно означает, что ты передаёшь указатель на массив. Единственный способ передать массив по значению (чтобы внутри вызванной функции его можно было менять, а в точке вызова он не изменился) - завернуть его в структуру

На всякий случай, как с точки зрения языка Си построена работа с массивами: Ошибка Lvalue required
0
alkagolik
Заблокирован
07.07.2012, 15:06 5
luck, дело в том что статический массив любой размерности фактически всегда является одномерным т.к. его размер известен на стадии компиляции и изменить его (размер) нельзя. В твоем примере при передаче в функцию он будет иметь тип double (*) [ 100 ] если я не ошибаюсь. Твоя функция прекрасно отработает если ты ей действительно передашь указатель на указатель - double**. Для этого тебе надо будет выделить необходимый размер памяти. А поскольку статический массив всегда одномерный, то и функцию можно реализовать как с одномерным массивом или же объявить как сказал Evg если необходимо работать в разброс "ячейками матрицы" чтобы не вычислять каждый раз необходимый адрес.
прримерчик
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 <stdio.h>
 
void foo( int* array, const size_t size ) {
    size_t i = 0;
    int value = 1;
 
    while( i < size )
        array[ i++ ] = value++;
}
 
void print_array ( int* array, const size_t row, const size_t colm ) {
    size_t i = 0, j, current = 0;
 
    while( i < row ) {
        for ( j = 0; j < colm; ++j )
            printf( "%3i", array[ current++ ] );
        putchar('\n');
        ++i;
    }
    puts("");
}
 
int main() {
 
    /*SetConsoleCP(1251);
    SetConsoleOutputCP(1251);*/
 
#define SIZE_OF_ARRAY   ( 5 )
 
    int array[ SIZE_OF_ARRAY ][ SIZE_OF_ARRAY ];
 
    foo( &array[ 0 ][ 0 ], SIZE_OF_ARRAY * SIZE_OF_ARRAY );
    print_array( array, SIZE_OF_ARRAY, SIZE_OF_ARRAY );
    //обрати внимание - передается в функции по разному, а фактически одинаково.
 
    return 0;
}
0
Evg
Эксперт CАвтор FAQ
19638 / 7330 / 551
Регистрация: 30.03.2009
Сообщений: 20,508
Записей в блоге: 30
07.07.2012, 16:41 6
Цитата Сообщение от alkagolik Посмотреть сообщение
Твоя функция прекрасно отработает если ты ей действительно передашь указатель на указатель - double**
Это работать не будет. А вот если передать одномерный массив из 10000 элементов, то будет
0
alkagolik
Заблокирован
07.07.2012, 16:47 7
Evg, ты просто не понял, я вот про что говорил
C
1
2
3
4
5
6
7
8
int main() {
 
    double **a;
 
    /* allock a */
    func( a, size, size );
    return 0;
}
конечно за исключением того что вложенный цикл функции func, косячный, а если исправить отработает.
0
Evg
Эксперт CАвтор FAQ
19638 / 7330 / 551
Регистрация: 30.03.2009
Сообщений: 20,508
Записей в блоге: 30
07.07.2012, 16:51 8
Цитата Сообщение от alkagolik Посмотреть сообщение
Evg, ты просто не понял
ТС, думаю, тоже не понял Возможно, даже и после этого примера

Добавлено через 1 минуту
"alloc" кстати тоже работать не будет (для этого нужно &a передать). А таким образом только "init"
0
alkagolik
Заблокирован
07.07.2012, 19:08 9
Цитата Сообщение от Evg Посмотреть сообщение
ТС, думаю, тоже не понял Возможно, даже и после этого примера
так разберет
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
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
 
void foo( int** array, const size_t row, const size_t colm ) {
    size_t i = 0, j;
    int value = 1;
 
    while( i < row ) {
        for( j = 0; j < colm; ++j )
            array[ i ][ j ] = value++;
        ++i;
    }
}
 
void print_array ( int** array, const size_t row, const size_t colm ) {
    size_t i = 0, j;
 
    while( i < row ) {
        for ( j = 0; j < colm; ++j )
            printf( "%3i", array[ i ][ j ] );
        putchar('\n');
        ++i;
    }
    puts("");
}
 
int main() {
 
    /*SetConsoleCP(1251);
    SetConsoleOutputCP(1251);*/
#define SIZE_OF_ARRAY   ( 5 )
    int **a, i;
 
    if ( !( a = malloc( SIZE_OF_ARRAY * sizeof(int*) ) ) )
        perror( " error memory\n" );
    for ( i = 0; i < SIZE_OF_ARRAY; ++i )
        if ( !( a[ i ] = malloc( SIZE_OF_ARRAY * sizeof(int) ) ) )
            perror( " error memory\n" );
 
    foo( a, SIZE_OF_ARRAY, SIZE_OF_ARRAY );
    print_array( a, SIZE_OF_ARRAY, SIZE_OF_ARRAY );
    
    for ( i = 0; i < SIZE_OF_ARRAY; ++i )
        free( a[ i ] );
    free( a );
 
    return 0;
}
Добавлено через 49 секунд
Цитата Сообщение от Evg Посмотреть сообщение
"alloc" кстати тоже работать не будет (для этого нужно &a передать). А таким образом только "init"
тот коммент читается как TODO
1
luck
0 / 0 / 0
Регистрация: 06.07.2012
Сообщений: 63
07.07.2012, 20:42  [ТС] 10
Исправил свой пример до такого вида -
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
#include <stdio.h>
#include <math.h>
//--------------------------
 void func (double **a, int i, int j)
  {
   for (i=0;i<10;i++)
    for (j=0;j<10;j++)
     a[i][j]=i+j;
  }
main()
 {
  double **a;
  int i = 0;
  int j = 0;
  a=malloc(10*sizeof(double*));
  for (;i<10;++i)
   a[i]=malloc(10*sizeof(double));
  func(a,i,j);
  for (i=0;i<10;i++)
   for (j=0;j<10;j++)
    {
     printf("%f",a[i][j]);
     printf("\n");
    } 
  for (i=0;i<10;++i)
   free(a[i]);
  free(a);
  getch();
 }
Немного не разобрался со строками
a=malloc(10*sizeof(double*));
a[i]=malloc(10*sizeof(double));
но наверное сам соображу. Все правильно сделано?
А ещё вопрос - как в трассировке следить за значениями массива?
0
alkagolik
Заблокирован
07.07.2012, 23:17 11
Цитата Сообщение от luck Посмотреть сообщение
Немного не разобрался со строками
a=malloc(10*sizeof(double*));
a[i]=malloc(10*sizeof(double));
у нас имеется указатель на указатель типа double: double**. Ты даешь инструкцию указателю на указатель дать памяти под массив указателей на double: double*. Дальше каждому элементу массива ты даешь инструкцию дать памяти под double.
Цитата Сообщение от luck Посмотреть сообщение
Все правильно сделано?
с точки зрения синтаксиса да. Лучше функцию main() объявить как int и по завершении вернуть из нее значение. Константы лучше объявлять один раз, чем стопицот раз переписывать по всему коду в случае необходимости.
Цитата Сообщение от luck Посмотреть сообщение
А ещё вопрос - как в трассировке следить за значениями массива?
если ты имеешь ввиду пошаговую отладку, то очевидно надо почитать как пользоваться твоим отладчиком. в gdb это display <value>\ undsplay <value_number>
1
07.07.2012, 23:17
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
07.07.2012, 23:17

Как закинуть двумерный массив в функцию?
Не переводя в одномерный, конечно. #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;time.h&gt;...

Как по значению передать в функцию двумерный массив?
Всем привет! Имеется код, обнуляющий элементы ниже побочной диагонали в матрице и печатающий ее:...

Как по значению передать в функцию двумерный массив?
Имеется код, обнуляющий элементы ниже побочной диагонали в матрице и печатающий ее: int i, j;...


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

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru