Thread: How to pass multi-dim array to a function?

  1. #1
    Registered User
    Join Date
    Feb 2021
    Posts
    3

    How to pass multi-dim array to a function?

    I'm a beginner and my question is


    Why does this work
    Code:
    #include <stdio.h>
    void how(int array[]){
       array[420]=69;
        
    }
    int main(){
        int array[421];
        how(array);
        printf("%d", array[420]);
        
        
    }
    But this one doesn't?

    Code:
    #include <stdio.h>
    void how(int array[][]){
       array[420][69]=69;
        
    }
    int main(){
        int array[421][70];
        how(array);
        printf("%d", array[420][69]);
        
        
    }
    
    //why it doesnt work :(

  2. #2
    Registered User
    Join Date
    Feb 2021
    Posts
    3
    I understood that to the function is just passed the address of the array, but how can I give to it an array and the length of the dimensions that are given from user input , like
    Code:
    #include <stdio.h>
    void how(int array[][], int x, int y){
       array[x-1][y-1]=69;
        
    }
    int main(){
        int rows, columns;
        scanf("%d",&rows);
        scanf("%d",&columns);
        int matrix[rows][columns];
        how(matrix, rows, columns);
        printf("%d", matrix[rows-1][columns-1]);
        
        
    }

  3. #3
    Registered User
    Join Date
    Mar 2020
    Posts
    15
    If you use a fixed size matrix you can use:
    Code:
    void how(int (*array)[421][70]){
       (*array)[420][69]=69;
    }

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Some examples.
    Code:
    #include <stdio.h>
    
    
    void test1() {
      int foo = 1;
      int bar[10] = { 2 };
      int baz[10][10] = { { 3 } };
      printf("%d\n", foo);
      printf("%d\n", bar[0]);
      printf("%d\n", baz[0][0]);
    }
    
    // copy/paste the declaration of the variable you want to pass
    void foofn(int foo) {
      printf("%d\n", foo);
    }
    void barfn(int bar[10]) {
      printf("%d\n", bar[0]);
    }
    void bazfn(int baz[10][10]) {
      printf("%d\n", baz[0][0]);
    }
    
    void test2() {
      int foo = 1;
      int bar[10] = { 2 };
      int baz[10][10] = { { 3 } };
      foofn(foo);
      barfn(bar);
      bazfn(baz);
    }
    
    void how(int rows, int cols, int mat[rows][cols] ) {
      printf("%d\n", mat[0][0]);
    }
    
    void test3() {
      int rows = 2;
      int cols = 3;
      int mat[rows][cols];  //!! this is only allowed in C99
      mat[0][0] = 4;
      how(rows,cols,mat);
    }
    
    int main ( ) {
      test1();
      test2();
      test3();
      return 0;
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    Incomplete array declarations can be "incomplete" only in the "first" dimension. The reason is this: Suppose you have an array like yours:
    Code:
    int arr[421][69];
    To access the element arr[i][j] the compiler uses the base pointer (arr) and the offset 69*i+j to find the correct element.. So, all the elements, except the "first" must be known by the compiler. This way, you can pass an incomplete array as argment this way:
    Code:
    int f( int arr[][69] ) { return arr[3][6]; }
    Here, the offset will be 69*3+6 (213).
    Another way to do it is to work with pointers, but your code must know the dimensions, the same code as above, but using a single pointer (as a base for the array, could be:
    Code:
    int f( int *arr ) { return a[69*3+6]; }
    You only have to be cautions to pass this pointer correctly:
    Code:
    int arr[421][69];
    ...
    y = f( (int *)arr );
    Of course, you can pass the dimensions of your array (not the first one) to the function:
    Code:
    int f( int *arr, unsigned int columns,
           unsigned int i, unsigned int j )
    { return arr[columns * i + j]; }
    Now, let's consider a three dimmentional array:
    Code:
    int arr[3][4][5];
    The principle is the same... find an element (i,j,k) from a array with dimmentions (x,y,z) the offset is calculated as: (y*z*i + z*j + k). So the incomplete array, again, has the "first" element empty because it isn't needed to calculate the offset (which will be added to the base pointer 'arr'):
    Code:
    int f( int arr[][4][5] ) { return arr[3][3][3]; }
    Or:
    Code:
    int f( int *arr, unsigned int y, unsigned int z,
           unsigned int i, unsigned int j, unsigned k )
    {
      return arr[y*z*i + z*j + k];
    }
    Last edited by flp1969; 02-07-2021 at 10:32 AM.

  6. #6
    Registered User
    Join Date
    May 2012
    Posts
    505
    Multi-demensional arrays are often taught in beginners' books shortly after single dimensional arrays. I'ts not normally made clear that they are an advanced feature in C. If the array has dimensions known at compile time, and you use it only in the function where it is declared, everything does indeed work as you would expect. But as soon as you try to pass multi-dimensional arrays to subroutines, or have dimensions determined at run time, the difficulties start.

    Most C programmers simply use 1 dimensional arays, even for data like raster images which are inherently two dimensional. They they calculate the indices explicitly at the time of access (array[y*width+x]).
    I'm the author of MiniBasic: How to write a script interpreter and Basic Algorithms
    Visit my website for lots of associated C programming resources.
    https://github.com/MalcolmMcLean


  7. #7
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    945
    C99 and later support this type of function declaration:

    Code:
    void how(int x, int y, int array[x][y]);
    Then you just have to pass in the two dimensions (x and y) of the array when you call it.

    If you can't use a compiler that supports C99 (which is already 21+ years old at this point), then you'll have to use another method.

  8. #8
    Registered User
    Join Date
    May 2010
    Posts
    4,633
    C99 and later support this type of function declaration:
    Are you sure? VLA are only truly supported in C99, in C11 VLA use is an optional feature, not all compilers support the use of VLA when using the current standard.

  9. #9
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    945
    Quote Originally Posted by jimblumberg View Post
    Are you sure? VLA are only truly supported in C99, in C11 VLA use is an optional feature, not all compilers support the use of VLA when using the current standard.
    I'm not 100% sure, no. Is that considered a true VLA, though? I thought (perhaps mistakenly) that a VLA was only an automatic variable array whose size was determined at run time. A function parameter, in my mind, is not a VLA because it's simply telling the function how big the array already is. But if it's still considered a VLA, then this isn't guaranteed to work in C after C99.

  10. #10
    Registered User
    Join Date
    May 2010
    Posts
    4,633
    Is that considered a true VLA, though?
    Yes. Remember that function parameters all but the last array subscript of an array must utilize a compile time constant size.

  11. #11
    Registered User
    Join Date
    Feb 2021
    Posts
    3
    Thank you all for the clarification 😊

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 11
    Last Post: 10-20-2019, 02:00 PM
  2. Replies: 2
    Last Post: 01-10-2016, 01:23 AM
  3. pass a multi-dimensional array by argument
    By carlorfeo in forum C++ Programming
    Replies: 12
    Last Post: 03-03-2008, 11:17 AM
  4. Replies: 1
    Last Post: 10-21-2007, 07:44 AM
  5. Replies: 3
    Last Post: 04-02-2002, 01:39 PM

Tags for this Thread