简体   繁体   中英

Passing a 2D array to a function in C?

I need to pass a 2D array to a function.

#include <stdio.h>

#define DIMENSION1 (2)
#define DIMENSION2 (3)

void func(float *name[])
{
    for( int i=0;i<DIMENSION1;i++){
        for( int j=0;j<DIMENSION2;j++){
            float element = name[i][j];
            printf("name[%d][%d] = %.1f \n", i, j, element);
        }
    }
}


int main(int argc, char *argv[])
{
        float input_array[DIMENSION1][DIMENSION2] = 
        { 
            {0.0f, 0.1f, 0.2f}, 
            {1.0f, 1.1f, 1.2f} 
        };

        func(input_array);

        return 0;
}

Dimensions vary depending on the use case, and the func should stay the same.

I tried the above int func(float *[]) but compiler complains expected 'float **' but argument is of type 'float (*)[3]' , and also I get the segmentation fault error at runtime when trying to access the array at element = name[i][j] .

What would be the proper signature of my function? Or do I need to call the func differently?

You can change your function like this;

int func(float (*arr)[DIMENSION2])
{

}

But also you should change your main code like this;

float input[DIMENSION1][DIMENSION2];//I just upload the dimension1 to dimension2

If you are using varying size object, then you should encapsulate it in a struct .

struct array2D
{
  int rows, columns;
  float values[1];
};
typedef struct array2D array2D;

array2D * create2D( int rows, int columns )
{
  array2D * result = calloc( sizeof(array2D) + sizeof(float) * rows * columns - 1, 1 );
  if (result)
  {
    result->rows = rows;
    result->columns = columns;
  }
  return result;
}

float * index2D( array2D * a, int row, int column )
{
  return a->values + row * a->rows + column;
} 

And so on.

void my_fn( array2D * A )
{
  *index2D( A, A->rows-1, A->columns-1 ) = -7;
}

int main()
{
  array2D * A = create2D( 3, 4 );
  *index2D( A, 1, 2 ) = 3.141592;
  my_fn( A );
  for (int row = 0; row < A->rows; row++)
  {
    for (int col = 0; col < A->columns; col++)
      printf( "%10.2f ", *index2D( A, row, col ) );
    printf( "\n" );
  }
  free( A );
}

EDIT: With this structure, you can even deal with individual rows:

void my_fn2( float * row, int n )
{
  row[n-1] = 5;
}

int main()
{
  ...
  my_fn2( index2D( A, 2, 0 ), A->columns );
  ...
}

You can use the following function prototype:

int func(int dim1, int dim2, float array[dim1][dim2]);

For this you have to pass both dimensions to the function (you need this values anyhow in the function). To improve the usability of the function call, you can use the following macro:

#define FUNC_CALL_WITH_ARRAY(array) func(sizeof(array)/sizeof(*(array)), sizeof(*(array))/sizeof(**(array)), array)

Then you can call the function with:

FUNC_CALL_WITH_ARRAY(input_array);

Full example:

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

#define FUNC_CALL_WITH_ARRAY(array) func(sizeof(array)/sizeof(*(array)), sizeof(*(array))/sizeof(**(array)), array)
int func(int dim1, int dim2, float array[dim1][dim2])
{
    printf("dim1 %d, dim2 %d\n", dim1, dim2);

    return 0;
}

#define DIMENSION1 (4)
#define DIMENSION2 (512)



int main(int argc, char *argv[])
{
    float input_array[DIMENSION1][DIMENSION2];

    FUNC_CALL_WITH_ARRAY(input_array);

    float input_array2[7][16];

    FUNC_CALL_WITH_ARRAY(input_array2);
}

Will print

dim1 4, dim2 512
dim1 7, dim2 16

Dimensions vary depending on the use case, and the func should stay the same.

Use VLA:

void func (int r, int c, float arr[r][c]) {
    //access it like this
    for (int i = 0; i < r; ++i) {
        for (int j = 0; j < c; ++j) {
            printf ("%f\n", arr[i][j]);
        }
    }
}

// call it like this

func (DIMENSION1, DIMENSION2, input_array);

As noted above in the comment, the key problem is that int func(float *name[]) declares name to be an array of pointers to float .

In this sense, the following modification to main() works:

int main(int argc, char *argv[])
{
        float input_array[DIMENSION1][DIMENSION2] = 
        { 
            {0.0f, 0.1f, 0.2f}, 
            {1.0f, 1.1f, 1.2f} 
        };

        /* Declare an array of pointers, as this is what func requires at input: */
        float* in_p[DIMENSION1];       
        /* ... and initialize this array to point to first elements of input array: */
        for( int i=0;i<DIMENSION1;i++)
            in_p[i] = input_array[i];
        /* ... and send this array of pointers to func: */
        func(in_p);

        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