The rule of "array decay" means that whenever you use an array name a as part of an expression, it "decays" to a pointer to the first element.
For a 1D array, this is pretty straight forward. An array int a [10] would decay into type int*.
However, in case of two-dimensional arrays, the first element of the 2D array is a 1D array. In your case, the first element of int a[3][4] has array type int [4].
The array decay rule gives you a pointer to such an array, an array pointer, of type int (*)[4]. This type is not compatible with the type int* that your function expects.
However, by sheer luck, it would appear the the array pointer and a plain int pointer have the same representation on your system, and they happen to hold the same address, so the code works. You shouldn't rely on this though, it is not well-defined behavior and there is no guarantee it will work.
You should fix your program in the following way:
#include
void display (int row, int col, int arr[row][col]);
int main()
{
int a[3][4]=
{
{2,3,4,5},
{5,7,6,8},
{9,0,1,6},
};
display(3, 4, a);
return 0;
}
void display (int row, int col, int arr[row][col])
{
for(int i=0; i<row; i++)
{
for(int j=0; j<col; j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
printf("\n");
}
Here the array type that is the function parameter will silently "get adjusted" by the compiler to a pointer to the first element, int(*)[4], which matches what's passed to the function from the caller.