12

One can easily define a function that accepts a 1d array argument like this:

int MyFunction( const float arr[] )
{    
    // do something here, then return...

    return 1

}

Although a definition such as: int MyFunction( const float* arr ) would work as well.

How can one define a function that accepts a 2d array argument?

I know that this works: int MyFunction( const float** arr ) -- but, is it possible to use the first variation that uses []?

user3262424
  • 7,223
  • 16
  • 54
  • 84

5 Answers5

34

In C99, you can provide the dimensions of the array before passing it:

 void array_function(int m, int n, float a[m][n])
 {
      for (int i = 0; i < m; i++)
          for (int j = 0; j < n; j++)
              a[i][j] = 0.0;
 }


 void another_function(void)
 {
     float a1[10][20];
     float a2[15][15];
     array_function(10, 20, a1);
     array_function(15, 15, a2);
 }
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
6

Try something like this:

int MyFunction(size_t ncols, const float arr[][ncols])
{    
    // ...
}
R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
3

when we pass 2D array as a arguments to the functions it's optional to specify left most dimensions.The key point here is when any changes made in functions that changes reflects in calling functions because when we pass 2-D array as a arguments means actually functions receive pointer to 1-D array. And size of that is number of columns . examples

1 - int funct(int (*a) [4]);

here a is pointer to array of integer. we can simply pass like this also

2- void funct(int a[][4]);

as I said earlier left most side is always optional. In first example size of a will be 4 because it's normally just pointer. while size of *a will be 16 because we have 4 column and for each column we have 4 bytes so 4*4 = 16 bytes.

But most preferable way is always use dynamic memory allocations.

I hope u got clear

lost_in_the_source
  • 10,998
  • 9
  • 46
  • 75
0

The hackish way would be to pass the first element and do the array calculations manually.

This longish example uses a macro to semi-automatically extract the array dimensions to use in the call.

struct font { int disp, trig; };
struct font font3[3][3];
#define dim(x) (sizeof(x)/sizeof*(x))
#define font_and_dims(x) (struct font *)x, dim(x), dim(*x)
int print(char *s, struct font *font, int dimy, int dimx) { ... }

main(){ ...   print(*av, font_and_dims(font3));   ... }

The called function accesses the array the hard way.

print(){ ...   font[row*dimx+col]   ... }

Don't be afraid to scroll down: the good stuff is at the bottom! This ugly, pedantic function at the top provides ultimate charset portability; but it is an eyesore, I admit.

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

int ao(int c) {
    switch(c) {
    case '0':return 0;
    case '1':return 1;
    case '2':return 2;
    case '3':return 3;
    case '4':return 4;
    case '5':return 5;
    case '6':return 6;
    case '7':return 7;
    case '8':return 8;
    case '9':return 9;
    case 'A':case 'a':return 10;
    case 'B':case 'b':return 11;
    case 'C':case 'c':return 12;
    case 'D':case 'd':return 13;
    case 'E':case 'e':return 14;
    case 'F':case 'f':return 15;
    default:return -1;
    }
}

enum {
    A = 1 << 0,
    B = 1 << 1,
    C = 1 << 2,
    D = 1 << 3,
    E = 1 << 4,
    F = 1 << 5,
    G = 1 << 6,
    H = 1 << 7 };

int seg[] = {
    /*0*/ A|B|C|D|E|F,
    /*1*/   B|C,
    /*2*/ A|B|  D|E|  G,
    /*3*/ A|B|C|D|    G,
    /*4*/   B|C|    F|G,
    /*5*/ A|  C|D|  F|G,
    /*6*/ A|  C|D|E|F|G,
    /*7*/ A|B|C,
    /*8*/ A|B|C|D|E|F|G,
    /*9*/ A|B|C|    F|G,
    /*A*/ A|B|C|D|E|  G, /*A|B|C|  E|F|G,*/
    /*b*/     C|D|E|F|G,
    /*C*/       D|E|  G, /*A|    D|E|F,*/
    /*d*/   B|C|D|E|  G,
    /*E*/ A|B|  D|E|F|G, /*A|    D|E|F|G,*/
    /*F*/ A|      E|F|G,
};

struct font {
    int disp, trig;
};
/* _
  |_|
  |_|
*/
struct font font3[3][3] = {
    { {  0,0}, {'_',A}, {  0,0} },
    { {'|',F}, {'_',G}, {'|',B} },
    { {'|',E}, {'_',D}, {'|',C} },
};
/* ___
  |   |
  |___|
  |   |
  |___|
*/
struct font font5[5][5] = {
    { {  0,0}, {'_',A}, {'_',A}, {'_',A}, {  0,0} },
    { {'|',F}, {  0,0}, {  0,0}, {  0,0}, {'|',B} },
    { {'|',F}, {'_',G}, {'_',G}, {'_',G}, {'|',B} },
    { {'|',E}, {  0,0}, {  0,0}, {  0,0}, {'|',C} },
    { {'|',E}, {'_',D}, {'_',D}, {'_',D}, {'|',C} }
};
/* ____
  |    |
  |    |
  |    |
  |____|
  |    |
  |    |
  |    |
  |____|
*/
struct font font9[9][7] = {
    { {  0,0}, {'_',A}, {'_',A}, {'_',A}, {'_',A}, {  0,0}, {0,0} },
    { {'|',F}, {  0,0}, {  0,0}, {  0,0}, {  0,0}, {'|',B}, {0,0} },
    { {'|',F}, {  0,0}, {  0,0}, {  0,0}, {  0,0}, {'|',B}, {0,0} },
    { {'|',F}, {  0,0}, {  0,0}, {  0,0}, {  0,0}, {'|',B}, {0,0} },
    { {'|',F}, {'_',G}, {'_',G}, {'_',G}, {'_',G}, {'|',B}, {0,0} },
    { {'|',E}, {  0,0}, {  0,0}, {  0,0}, {  0,0}, {'|',C}, {0,0} },
    { {'|',E}, {  0,0}, {  0,0}, {  0,0}, {  0,0}, {'|',C}, {0,0} },
    { {'|',E}, {  0,0}, {  0,0}, {  0,0}, {  0,0}, {'|',C}, {0,0} },
    { {'|',E}, {'_',D}, {'_',D}, {'_',D}, {'_',D}, {'|',C}, {0,0} },
};

#define dim(x) (sizeof(x)/sizeof*(x))
#define font_and_dims(x) (struct font *)x, dim(x), dim(*x)

int print(char *s, struct font *font, int dimy, int dimx) {
    int row, col;
    char *sp;
    for (row = 0; row < dimy; row++) {
    for (sp = s; *sp; sp++) {
        for (col = 0; col < dimx; col++) {
            putchar( seg[ao(*sp)] & font[row*dimx+col].trig ?
                font[row*dimx+col].disp : ' ');
        }
    }
    putchar('\n');
    }
}

int main(int ac, char **av) {
    enum { F1, F2, F3 } fz = F1;
    for (++av,--ac;ac;ac--,av++) {
    if (av[0][0] == '-') {
        switch (av[0][1]) {
            case '1': fz=F1; continue;
            case '2': fz=F2; continue;
            case '3': fz=F3; continue;
            default: fprintf(stderr, "Unrecognized Option!\n");
        }
    }
    if (strspn(*av, "0123456789abcdefABCDEF") != strlen(*av))
        fprintf(stderr, "Hex only!\n");
    else
        switch(fz) {
            case F1: print(*av, font_and_dims(font3)); break;
            case F2: print(*av, font_and_dims(font5)); break;
            case F3: print(*av, font_and_dims(font9)); break;
            default: fprintf(stderr, "Invalid Font!\n");
        }
    }

    return 0;
}
luser droog
  • 18,988
  • 3
  • 53
  • 105
-2

In C89 u can use

typedef float OneRow[2];

void func(OneRow *arr)
{
  printf("%f",arr[1][0]);
}
...
  OneRow arr[] = {{1,2},{3,4},{5,6}};
  func(arr);
...
user411313
  • 3,930
  • 19
  • 16