简体   繁体   中英

Passing two-dimensional array via pointer

How do I pass the m matrix to foo()? if I am not allowed to change the code or the prototype of 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???);
}

If you insist on the above declaration of foo , ie

void foo(float **pm)

and on using a built-in 2D array, ie

float m[4][4];

then the only way to make your foo work with m is to create an extra "row index" array and pass it instead of m

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

There no way to pass m to foo directly. It is impossible. The parameter type float ** is hopelessly incompatible with the argument type float [4][4] .

Also, since C99 the above can be expressed in a more compact fashion as

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

PS If you look carefully, you'll that this is basically the same thing as what Carl Norum suggested in his answer. Except that Carl is malloc -ing the array memory, which is not absolutely necessary.

If you can't change foo() , you will need to change m . Declare it as float **m , and allocate the memory appropriately. Then call foo() . Something like:

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;
    }
}

Don't forget to free() afterwards!

You can't. m is not compatible with the argument to foo . You'd have to use a temporary array of pointers.

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);
  • you dont need to do any changes in the main,but you function will work properly if you change the formal prototype of your function to (*pm)[4] or pm[][4] because **pm means pointer to pointer of integer while (*pm)[4] or pm[][4] means pointer to poiner of 4 integers .

    m here is also a pointer to pointer of 4 integers and not pointer to pointer of integers and hence not compatible.

     #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); } 

If you have a compiler that supports C99, the current C standard, then you can do this:

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

(Note that this is exactly the same as AndreyT 's answer, except that it forgoes having to name the temporary array)

foo(m)不起作用吗?

void foo(float **pm) is the same as void foo(float *pm[]) which is not a two-dimensional array of floats. It is an array of float* . Now, those float* may themselves point to float arrays, but that's a separate matter.

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;
}

Using C99 which supports run-time sized arrays, the following is a possible way to pass a 2-dim array:

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM