Передача двумерного массива с помощью указателя
Как передать 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;
}