2

I am trying to pass a multi dimensional array as a parameter to a function. Here is my complete code :

#include <stdio.h>

----> void transpose( int , int, int[int][int] ) ;

void main() {
    int row = 0, col = 0 ;
    int tempRow = 0, tempCol = 0 ;
    printf("\nEnter no of rows and colummns in the matrix :\t") ;
    scanf("%d %d", &row, &col) ;
    int matrix [row][col] ;
    printf("\n") ;
    for ( tempRow ; tempRow < row ; tempRow++) {
        for ( tempCol ; tempCol < col ; tempCol++) {
            scanf("%d" , &matrix[ tempRow][ tempCol] ) ;
            printf("\t") ;
        }
        printf("\n") ;
    }
    -----> transpose(row, col, matrix) ;
}

-----> void transpose(int row, int col, int matrix[row][col]) {
int temp[row][col] ;
int tempRow = 0 , tempCol = 0 ;
for( tempRow ; tempRow < row ; tempRow++) {
    for( tempCol  ; tempCol < col ; tempCol++) {
        temp[tempRow][tempCol] = matrix[tempCol][tempRow] ;
        printf("%d\t", temp[tempRow][tempCol]) ;
    }
    printf("\n") ;
}
}

I have marked -----> where I think error is.

Error :

matrixTranspose.c:3:32: error: expected expression before ‘int’
void transpose( int , int, int[int][int] ) ;
                            ^
matrixTranspose.c:22:6: warning: conflicting types for ‘transpose’ [enabled by default]
void transpose(int row, int col, int matrix[row][col]) {
  ^
matrixTranspose.c:19:2: note: previous implicit declaration of ‘transpose’ was here
transpose(row, col, matrix) ;

I tried looking this post but was unable to detect the error. Also if I replace function prototype with this :

void transpose( int, int, int[][]) 

then it says function definition incomplete.

So how do I pass a variable sized multi dimensional array ( possibly by avoiding pointers ) ?


Edit :

I had already tried these modifications earlier :

void transpose( int, int , int [] [int] )   //type 1

void transpose( int , int , int[] [col] )   //type 2

None of them work. Here is the error generated

for type 1 :

matrixTranspose.c:3:34: error: expected expression before ‘int’
void transpose( int , int, int[][int] ) ;
                              ^
matrixTranspose.c:22:6: warning: conflicting types for ‘transpose’   [enabled by default]
void transpose( int row, int col, int matrix[row][col]) {
  ^
matrixTranspose.c:19:2: note: previous implicit declaration of ‘transpose’ was here
transpose(row, col, matrix) ;

For type 2 :

matrixTranspose.c:3:34: error: ‘col’ undeclared here (not in a function)
void transpose( int , int, int[][col] ) ;
                              ^
matrixTranspose.c: In function ‘main’:
matrixTranspose.c:19:2: error: type of formal parameter 3 is incomplete
transpose(row, col, matrix) ;
^
  matrixTranspose.c:19: confused by earlier errors, bailing out
  Preprocessed source stored into /tmp/ccasypOi.out file, please attach this to your bugreport.
Community
  • 1
  • 1
Plutonium smuggler
  • 329
  • 5
  • 6
  • 17
  • `void main()` should be `int main(void)`. – mch Jun 19 '15 at 13:47
  • @mch `void main()` is perfectly acceptable in C (though some compilers choke on it). – Shotgun Ninja Jun 19 '15 at 13:48
  • @ShotgunNinja I'm afraid, not. §5.1.2.2.1, `C11`. – Sourav Ghosh Jun 19 '15 at 13:48
  • @SouravGhosh. Edited my post. – Plutonium smuggler Jun 19 '15 at 13:55
  • Now, your last line worries me, the "(possibly by avoiding pointers)" part. You can't avoid pointers in C, if you're going to be doing anything of value with them. Embrace them and learn them well. That being said, C99 supports two-dimensional arrays as function arguments, but ignores the first dimension. So, you can do `void func(int m, int n, int a[m][n])`, but `m` will not be enforced by the function call. In C89, you'd need to declare it as `void func(int m, int n, int** a)`, but the rest of the code will work the same (unless you do sizeof). – Shotgun Ninja Jun 19 '15 at 13:58
  • @ShotgunNinja . But that declaration isnt working. I've edited the post to include that. Note : void main () is OK in my system. – Plutonium smuggler Jun 19 '15 at 13:59
  • @SouravGhosh In `C11` it's not acceptable. In `C89` it is. In some compilers (like many used in embedded and Arduino) they either allow or enforce `void main()`. Also, 5.1.2.2.1 only applies to hosted environments; this can be ignored for C running on-the-metal. I'm just being nitpicky. – Shotgun Ninja Jun 19 '15 at 14:01
  • @Plutoniumsmuggler it's possible your compiler is aimed towards an older version of C (such as `C89`). If that's the case, you'd need to declare the argument in the function signature as a double-pointer to int (`int**`), but you may use it (once initialized) the same as a 2d array. – Shotgun Ninja Jun 19 '15 at 14:02
  • @ShotgunNinja . Does the fact that my complier crashes (as mentioned in the bottom most error ) means its C89 , and it leaves me with no other option but to use double pointer declaration ? And otherwise if I were using C99 or C11, which of the declarations i tried would be ok ? – Plutonium smuggler Jun 19 '15 at 14:05
  • Have you tried using the `-std=c99` compiler flag? – Shotgun Ninja Jun 19 '15 at 14:10
  • 1
    If you were using C99 or C11, then `void func(int rows, int cols, int[][cols])` would be the preferred signature. – Shotgun Ninja Jun 19 '15 at 14:12

3 Answers3

3

In short, you can't without relying on a certain compiler. Pre-C99 doesn't allow multi-dimensional array function arguments where there are more than one unknown dimension.

However, do not despair! C caters for this using linear indexing. There's a great link which covers the topic in detail, but as a short answer to your problem, you can fix your problem as follows:

void transpose(int row, int col, int matrix[]) 
{
    int temp[row][col] ;
    int tempRow = 0 , tempCol = 0 ;

    for( tempRow ; tempRow < row ; tempRow++) 
    {
        for( tempCol  ; tempCol < col ; tempCol++) 
        {
        temp[tempRow][tempCol] = matrix[(tempCol * col) + tempRow] ;
        printf("%d\t", temp[tempRow][tempCol]) ;
    }
    printf("\n") ;
    }
}

Where matrix[(tempCol * col) + tempRow] is the linear index that does the magic for you, as C can also treat your multidimentional array of row rows and col columns as a one-dimensional array which is row*col elements long (which in fact it actually is in memory).

There's also another SO question discussing accessing an array like this in C.

Community
  • 1
  • 1
Matt Taylor
  • 3,360
  • 1
  • 20
  • 34
  • Hmm, your answer was the only correct one until C99. But compilers conforming to C99 standard now support Variable Length Arrays. So it is now only correct for K&R C and ANSI C :-) – Serge Ballesta Jun 19 '15 at 14:47
  • @SergeBallesta very true, although I'd always prefer to know how to do something in C without relying on C99 being a compiler option (I work on embedded platforms where such luxuries aren't always available) ;-) – Matt Taylor Jun 19 '15 at 14:54
2

You need to change

 void transpose( int , int, int[int][int] ) ;

to

 void transpose( int row, int col, int[ ][col] ) ;

and compile using -std=c99

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
1

Declare the function simply like

void transpose( int row, int col, int[][col] ) ;

provided that your compiler supports Variable Length Arrays.

The other way that is close to your attempts to declare the function is

void transpose( int , int , int [][*] );

Here is a demonstrative program

#include <stdio.h>

void f( int , int , int [][*] );

int main(void)
{
    int row = 10;
    int col = 10;

    int a[row][col];

    f( row, col, a);

    for ( int i = 0; i < row; i++ )
    {
        for ( int j = 0; j < col; j++ ) printf( "%2d ", a[i][j] );
        printf( "\n" );
    }

    return 0;
}

void f( int row, int col, int a[][col] )
{
    for ( int i = 0; i < row; i++ )
    {
        for ( int j = 0; j < col; j++ ) a[i][j] = i * col + j;
    }
}

The program output is :)

 0  1  2  3  4  5  6  7  8  9 
10 11 12 13 14 15 16 17 18 19 
20 21 22 23 24 25 26 27 28 29 
30 31 32 33 34 35 36 37 38 39 
40 41 42 43 44 45 46 47 48 49 
50 51 52 53 54 55 56 57 58 59 
60 61 62 63 64 65 66 67 68 69 
70 71 72 73 74 75 76 77 78 79 
80 81 82 83 84 85 86 87 88 89 
90 91 92 93 94 95 96 97 98 99 
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335