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 []?

5
  • float **arr is not a 2D array despite that it "looks like" one. Commented Jul 28, 2011 at 17:10
  • Thanks. So how do I define a function that accepts a 2d array? Commented Jul 28, 2011 at 17:12
  • possible duplicate of Passing arrays and matrices to functions as pointers and pointers to pointers in C Commented Jul 28, 2011 at 17:17
  • "2d array" is an ambiguous name, it can be used to designate several different C constructs. Please show us a declaration. Commented Jul 28, 2011 at 17:17
  • See my answer. Note that it depends on C99. If the second dimension is a constant, you can just write the constant explicitly and then your code will work with older versions of C too. Commented Jul 28, 2011 at 17:19

5 Answers 5

35

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);
 }
Sign up to request clarification or add additional context in comments.

7 Comments

By the way, the first dimension is actually unnecessary. It's ignored by the compiler.
Jonathan, thank you. Given your answer, will the above prototype work for 1d array: void array_function(int n, float a[n])?
@user326424: yes, you can adapt it to a 1D array as suggested. Though how much you gain depends a bit on the comment by R..
@R Does that leave the size of the inner arrays or the outer array undefined?
@QPaysTaxes: specifying int a[][23] means you have an array of unknown length where each element of the array is an array of known size.
|
7

Try something like this:

int MyFunction(size_t ncols, const float arr[][ncols])
{    
    // ...
}

5 Comments

Your answer should note that this is a C99-specific construct.
To me and many people on this site, "C" means the current version of the C standard at the time of writing, i.e. C99. But yes, noted, this does require C99. As in my comment on the original post, if ncols is a constant, you can do the same in pre-C99 C.
Are you sure about the pre-C99 thing? Do you mean if ncols is const size_t, or are you talking about something else?
I'm talking about if ncols is an integer constant expression like 42 or sizeof(int). const-qualified variables are not constants in C.
Sure, but that's something different to what you're proposing above!
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

Comments

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

Comments

-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);
...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.