Как написать функцию переменного тока, которая может принимать как динамический / статически распределенный 2D-массив?

У меня есть функция, которая должна принимать 2D-массив в качестве аргумента, мой код выглядит так -

#include <stdio.h>
#include <stdlib.h>

void func(double**, int);

int main()
{
    double m[3][3] = {{1, 1, 1}, {2, 2, 2}, {3, 3, 3}};
    func(m, 3);
}

void func(double **m, int dim)
{
    int i, j ;
    for(i = 0 ; i < dim ; i++)
    {
        for(j = 0 ; j < dim ; j++)
            printf("%0.2f ", m[i][j]);
        printf("\n");
    }
}

Тогда компилятор говорит -

test.c: In function ‘main’:
test.c:9:2: warning: passing argument 1 of ‘func’ from incompatible pointer type [enabled by default]
  func(m, 3);
  ^
test.c:4:6: note: expected ‘double **’ but argument is of type ‘double (*)[3]’
 void func(double**, int);
      ^

Но когда я говорю -

int main()
{
    int i, j;
    double m[3][3] = {{1, 1, 1}, {2, 2, 2}, {3, 3, 3}};
    double **m1 ;
    m1 = (double**)malloc(sizeof(double*) * 3);
    for(i = 0 ; i < 3 ; i++)
    {
        m1[i] = (double*)malloc(sizeof(double) * 3);
        for(j = 0 ; j < 3 ; j++)
            m1[i][j] = m[i][j] ;
    }
    func(m1, 3);
    for(i = 0 ; i < 3 ; i++) free(m1[i]);
    free(m1);
}

Он компилируется и запускается.

Есть ли способ, которым я могу сделать func() взять как статически / динамически определенный 2D-массив? Я в замешательстве, так как я передаю указатель mпочему это не правильно для первого случая?

Означает ли это, что мне нужно написать две отдельные функции для двух разных типов аргументов?

1 ответ

Решение

Ваше динамическое распределение для двумерного массива неверно. Используйте это как:

double (*m1)[3] = malloc(sizeof(double[3][3]));

И тогда это будет работать.

Кроме того, измените прототип функции на:

void func(double m[][3], int dim)

Другой способ - использовать одномерный массив размера. w * h вместо двумерного массива.

Рабочий пример


Начиная с комментария @TheParamagnCroissant c99 и далее, вы также можете использовать VLA и изменять оба размера. (Вам нужно будет правильно разместить 2D-массив)

Измените подпись функции на:

void func(int dim, double[dim][dim]);  /* Second arg is VLA whose dimension is first arg */
/* dim argument must come before the array argument */

Рабочий пример

Другие вопросы по тегам