Passing two-dimensional array via pointer

前端 未结 9 1007
失恋的感觉
失恋的感觉 2020-11-28 14:04

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          


        
相关标签:
9条回答
  • 2020-11-28 14:15

    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);
    
    0 讨论(0)
  • 2020-11-28 14:16

    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!

    0 讨论(0)
  • 2020-11-28 14:17
    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;
    }
    
    0 讨论(0)
  • 2020-11-28 14:29

    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;
    }
    
    0 讨论(0)
  • 2020-11-28 14:31
    • 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);
       }
      
    0 讨论(0)
  • 2020-11-28 14:33

    If you insist on the above declaration of foo, i.e.

    void foo(float **pm)
    

    and on using a built-in 2D array, i.e.

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

    P.S. 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.

    0 讨论(0)
提交回复
热议问题