2

My function prototype is

int** rotate(int **arr, int row, int col, int fl);

where arr is the two dimensional array, row and col is the number of row and columns of the 2D array respectively, fl is a flag variable. If the value of fl is 0 then the array will be rotated right, if fl is 1 then the array will be rotated left.

I have called the function as follows:

int **res= rotate(arr, row, col, fl);

But I got one warning and one note

[Warning] passing argument 1 of 'rotate' from incompatible pointer type.

[Note] expected 'int **' but argument is of type 'int (*)[20]' 
Paolo
  • 20,112
  • 21
  • 72
  • 113
SB56
  • 17
  • 5
  • 5
    [Have a read](https://stackoverflow.com/questions/42094465/correctly-allocating-multi-dimensional-arrays). – StoryTeller - Unslander Monica Dec 20 '17 at 11:11
  • Did you declare arr as follows: int **arr – NSKBpro Dec 20 '17 at 11:15
  • Yet another answer: [SO: Variadic C function printing multiple 2-D char arrays](https://stackoverflow.com/a/47593733/7478597). Aside from dealing with var. args, it covers passing a 2D array to a function which still can be used as 2D array. – Scheff's Cat Dec 20 '17 at 11:16
  • You should post all the code needed to understand the question, such as the declarations of all variables you're passing at the call site. But this has been asked and answered many times anyway. Seriously, just search Google for _stackoverflow c pass 2d array_. – underscore_d Dec 20 '17 at 11:26
  • 3
    "`arr` is the two dimensional array," --> Not quite `arr` is a [pointer to pointer to int](https://cdecl.org/?q=int+**arr). Arrays are not pointers and pointers are not arrays even though their usage appears similar. – chux - Reinstate Monica Dec 20 '17 at 12:14

3 Answers3

3

A pointer to a pointer is different from a pointer to an array. Array-to-pointer decaying can only happen on the left-most side (e.g. int [3][20] to int (*)[20]).

Change your function declaration to

int** rotate(int (*arr)[20], int row, int col, int fl);

or more obviously,

int** rotate(int arr[][20], int row, int col, int fl);

Note you have to fix the size at compile-time.

iBug
  • 35,554
  • 7
  • 89
  • 134
  • 1
    Why suggest `typedef`ing a pointer, which is generally a bad idea? And this seems confusing, since OP can't declare `Array arr;` and expect this to work. Why not simply `rotate(int arr[][20], int row, int col, int fl);` or `rotate(int (*arr)[20], int row, int col, int fl);`? OP has not provided enough code to clarify what is expected of the return value `int **`. – ad absurdum Dec 20 '17 at 11:42
  • @DavidBowling Please suggest me a way to use this in the function's return value. – iBug Dec 20 '17 at 11:44
  • I don't follow... to use what in the function's return value? – ad absurdum Dec 20 '17 at 11:44
  • @DavidBowling OP's function prototype is `int** rotate(...)` – iBug Dec 20 '17 at 11:45
  • 1
    yes, that is OP's function prototype, which seems likely to be a mistake also. I suspect that `arr` is declared as a 2d array like `int arr[20][20]`, and that the return value is used to access the rotated array; but how? I imagine that there are further errors here which a [MCVE] from OP would clarify. – ad absurdum Dec 20 '17 at 11:48
2

If your compiler supports variable length arrays then the function declaration can look the following way

void rotate( size_t row, size_t col, int arr[][col], int fl);

or

void rotate( size_t row, size_t col, int arr[][col], _Bool fl);

In this case you can use arrays with different sizes.

Here is a demonstrative program

#include <stdio.h>

void rotate( size_t row, size_t col, int a[][col], _Bool fl )
{
    for ( size_t i = 0; i < ( fl ? row : col ); i++ )
    {
        for ( size_t j = 0; j < ( fl ? col : row ); j++ )
        {
            printf( "%d ", a[fl ? i : j][fl ? j : i] );
        }
        putchar( '\n' );
    }
}

#define N1  3

int main(void) 
{
    int a[][3] =
    {
        { 1, 2, 3 },
        { 4, 5, 6 }
    };

    rotate( sizeof( a ) / sizeof( *a ), N1, a, 0 );
    putchar( '\n' );

    rotate( sizeof( a ) / sizeof( *a ), N1, a, 1 );
    putchar( '\n' );

    return 0;
}

Its output is

1 4 
2 5 
3 6 

1 2 3 
4 5 6 

Otherwise if within the function you are going to create new arrays then the function can look as it is shown in the following demonstrative program.

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

int ** rotate( size_t, size_t, int a[][*], _Bool fl );

int ** rotate( size_t row, size_t col, int a[][col], _Bool fl )
{
    int **p = malloc( col * sizeof( int * ) );
    for ( size_t i = 0; i < col; i++ )
    {
        p[i] = ( int * )malloc( row * sizeof( int ) );
    }

    if ( fl )
    {
        for ( size_t i = 0; i < row; i++ )
        {
            for ( size_t j = 0; j < col; j++ )
            {
                p[col - j - 1][i] = a[i][j];
            }
        }
    }
    else
    {
        for ( size_t i = 0; i < row; i++ )
        {
            for ( size_t j = 0; j < col; j++ )
            {
                p[j][i] = a[row - i - 1][j];
            }
        }
    }

    return p;
}

#define M   2
#define N   3

int main(void) 
{
    int a[M][N] =
    {
        { 1, 2, 3 },
        { 4, 5, 6 }
    };

    int **p = rotate( M, N, a, 0 );

    for ( size_t i = 0; i < N; i++ )
    {
        for ( size_t j = 0; j < M; j++ )
        {
            printf( "%d ", p[i][j] );
        }
        putchar( '\n' );
    }
    putchar( '\n' );

    for ( size_t i = 0; i < N; i++ )
    {
        free( p[i] );
    }
    free( p );

    p = rotate( M, N, a, 1 );

    for ( size_t i = 0; i < N; i++ )
    {
        for ( size_t j = 0; j < M; j++ )
        {
            printf( "%d ", p[i][j] );
        }
        putchar( '\n' );
    }
    putchar( '\n' );

    for ( size_t i = 0; i < N; i++ )
    {
        free( p[i] );
    }
    free( p );

    return 0;
}

Its output is

4 1 
5 2 
6 3 

3 6 
2 5 
1 4 
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

From the example, I assume that you are using a static definition of arr.

The Pointer to pointer is not the same as a 2D array.

Change

int** rotate(int **arr, int row, int col, int fl);

to

int** rotate(int arr[][20], int row, int col, int fl);

Note that the no of columns will have to be defined before compilation.

Rishikesh Raje
  • 8,556
  • 2
  • 16
  • 31