Create a two dimensional int array and find the smallest and biggest member along with the indexes
The formulated task leaves a lot of room for interpretation. You chose to simplify several points.

Fill [the array]...now find...

I take this as &quot;create a function that finds...&quot;. This forces you to organize the program. Combining both (2D array, function) leads to a subtle problem - I ended up with a #define COLS 10, because that number (from your imagination also) has to be known to the function at compilation.
I also think setting max to 0 and min to INT_MAX is mixing up logic and parameters.
The other problem with a function is: how to return the bunch of results. I took your structs and put them into one.
The call at the center is:
struct minmax mm = minandmaxCOLS(array, nrows);
The function takes an array and number of rows. The caller can choose this value, but the number of cols must always be COLS.
If COLS is variable, then a 2D array is the wrong approach. Array of pointers works.
Instead of
array[10][10]

I have
int nrows = 10;
int array[nrows][COLS];

illustrating that the caller (main) can choose the rows, but not the cols, if it wants to use a function.
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;time.h&gt;
#include &lt;limits.h&gt;

#define COLS 10

/* Result type */
struct minmax {
    int min, minrow, mincol;
    int max, maxrow, maxcol;
};

/* scan for min and max in a 2D array &quot;a[][]&quot; with dims rows and COLS  */  
struct minmax
minandmaxCOLS(int a[][COLS], int rows) {

    int r, c;
    struct minmax result;
    
    /* Initialize result-struct before comparing in loop */  
    result.min = result.max = a[0][0];
    result.minrow = result.mincol = 0;
    result.maxrow = result.maxcol = 0;

    for (r = 0; r &lt; rows; r++)
        for (c = 0; c &lt; COLS; c++)
            if (a[r][c] &gt; result.max) {
                result.max = a[r][c];
                result.maxrow = r;
                result.maxcol = c;
            }
            else 
                if (a[r][c] &lt; result.min) {
                    result.min = a[r][c];
                    result.minrow = r;
                    result.mincol = c;
                }

    return result;
}

int main (void) {
    int nrows = 10;
    int array[nrows][COLS];

    srand(time(NULL));

    for (int i = 0; i &lt; nrows; i++)
        for (int j = 0; j &lt; COLS; j++) 
            array[i][j] = rand();

    /* A kind of test */ 
    //array[5][5] = -3;
    //array[6][7] = INT_MAX;
    
    struct minmax mm = minandmaxCOLS(array, nrows);

    printf(&quot;Max number: %d, row: %d, column: %d\n&quot;, mm.max, mm.maxrow, mm.maxcol);
    printf(&quot;Min number: %d, row: %d, column: %d\n&quot;, mm.min, mm.minrow, mm.mincol);

    return 0;
}

As a side effect you can now also search for min and max only in certain rows:
struct minmax mm = minandmaxCOLS(array+2, 1);
Output with &quot;test&quot; activated:
Min number: -3, row: 0, column: 5
&quot;row&quot; is now relative to the arg array+2. The &quot;2&quot; means &quot;two rows of 10 (COLS) ints&quot;. Same as &amp;array[2].

typedef
The function paramter list can be simplified by using a typedef. After defineing COLS as 10:
typedef int Arrcolsint_t [COLS];
This shows that an array of COLS integers is a basic unit. Now I can forget half (two thirds) of the details of &quot;a&quot;:
minandmaxCOLS(Arrcolsint_t a[], int rows) 
Same as:
minandmaxCOLS(Arrcolsint_t *a, ....
The advantage is you can use that type in several functions and only change the typedef itself. Without it is int a[][COLS] or int (*a)[COLS].
Row_t might be a better typedef name. Still there always is the compile time value 10 behind it all.