Передача двумерного массива с помощью указателя

Как передать m-матрицу в foo()? если мне не разрешено изменять код или прототип foo()?

void foo(float **pm)
{
    int i,j;
    for (i = 0; i < 4; i++)
        for (j = 0; j < 4; j++)
            printf("%f\n", pm[i][j]);

}

int main ()
{
    float m[4][4];

    int i,j;
    for (i = 0; i < 4; i++)
        for (j = 0; j < 4; j++)
            m[i][j] = i+j;

    foo(???m???);
}

Ответ 1

Если вы настаиваете на вышеуказанном объявлении foo, то есть

void foo(float **pm)

и при использовании встроенного 2D-массива, т.е.

float m[4][4];

тогда единственный способ сделать ваш foo работать с m - создать дополнительный массив строк и передать его вместо m

...
float *m_rows[4] = { m[0], m[1], m[2], m[3] };
foo(m_rows);

Невозможно передать m в foo напрямую. Это невозможно. Тип параметра float ** безнадежно несовместим с типом аргумента float [4][4].

Кроме того, поскольку C99 выше может быть выражено более компактно, так как

foo((float *[]) { m[0], m[1], m[2], m[3] });

P.S. Если вы посмотрите внимательно, вы поймете, что это в основном то же самое, что и Карл Норум в своем ответе. За исключением того, что Carl - это malloc - память массива, которая не является абсолютно необходимой.

Ответ 2

Если вы не можете изменить foo(), вам нужно будет изменить m. Объявите его как float **m и соответствующим образом распределите память. Затем вызовите foo(). Что-то вроде:

float **m = malloc(4 * sizeof(float *));
int i, j;
for (i = 0; i < 4; i++)
{
    m[i] = malloc(4 * sizeof(float));
    for (j = 0; j < 4; j++)
    {
        m[i][j] = i + j;
    }
}

Не забывайте free() после этого!

Ответ 3

Вы не можете. m не совместим с аргументом foo. Вам нужно будет использовать временный массив указателей.

int main()
{
    float m[4][4];
    int i,j;

    float *p[4];

    p[0] = m[0];
    p[1] = m[1];
    p[2] = m[2];
    p[3] = m[3];

    for (i = 0; i < 4; i++)
        for (j = 0; j < 4; j++)
            m[i][j] = i+j;


    foo(p);

Ответ 4

Если у вас есть компилятор, поддерживающий C99, текущий C-стандарт, вы можете сделать это:

foo((float *[]){ m[0], m[1], m[2], m[3] });

(Обратите внимание, что это точно так же, как AndreyT, за исключением того, что ему не нужно называть временный массив)

Ответ 5

  • вам не нужно делать никаких изменений в основном, но вы будете работать правильно, если вы измените формальный прототип своей функции на (* pm) [4] или pm [] [4], потому что ** pm означает указатель на указатель целого числа while (* pm) [4] или pm [] [4] означает указатель на poiner из 4 целых чисел.

    m здесь также указатель на указатель на 4 целых числа, а не указатель на указатель целых чисел и, следовательно, несовместимый.

    #include<stdio.h>
    void foo(float (*pm)[4])
    {
        int i,j;
        for (i = 0; i < 4; i++)
            for (j = 0; j < 4; j++)
                printf("%f\n", pm[i][j]);
    
    }
    
    int main ()
    {
        float m[4][4];
        int i,j;
        for (i = 0; i < 4; i++)
            for (j = 0; j < 4; j++)
                    m[i][j] = i+j;
    
        foo(m);
     }
    

Ответ 6

Не работает ли foo(m)?

Ответ 7

void foo(float **pm) совпадает с void foo(float *pm[]), который не является двумерным массивом поплавков. Это массив из float*. Теперь те float* могут сами указывать на массивы с плавающей точкой, но это отдельное дело.

Ответ 8

typedef float Float4[4];

void foo(Float4 *pm)
{
  int i,j;
  for (i = 0; i < 4; i++)
    for (j = 0; j < 4; j++)
      printf("%f\n", pm[i][j]);
}

main()
{
  Float4 m[4];

  int i,j;
  for (i = 0; i < 4; i++)
    for (j = 0; j < 4; j++)
      m[i][j] = i+j;

  foo(m);
  return 0;
}

Ответ 9

Используя C99, который поддерживает массивы размера времени выполнения, следующий способ - передать 2-мерный массив:

void foo(void *pm, int row, int col)
{
    float (*m)[col] = pm;

    for (int i = 0; i < row; i++)
        for (int j = 0; j < col; j++)
            printf("%4.1f%s", m[i][j], (j == col-1)?"\n":" ");

}

int main()
{
    float m[4][4];

    for (int i = 0; i < 4; i++)
        for (int j = 0; j < 4; j++)
            m[i][j] = i+j;

    foo(m, 4, 4);

    return 0;
}