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 "create a function that finds...". 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 <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <limits.h>
#define COLS 10
/* Result type */
struct minmax {
int min, minrow, mincol;
int max, maxrow, maxcol;
};
/* scan for min and max in a 2D array "a[][]" 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 < rows; r++)
for (c = 0; c < COLS; c++)
if (a[r][c] > result.max) {
result.max = a[r][c];
result.maxrow = r;
result.maxcol = c;
}
else
if (a[r][c] < 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 < nrows; i++)
for (int j = 0; j < 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("Max number: %d, row: %d, column: %d\n", mm.max, mm.maxrow, mm.maxcol);
printf("Min number: %d, row: %d, column: %d\n", 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 "test" activated:
Min number: -3, row: 0, column: 5
"row" is now relative to the arg array+2
. The "2" means "two rows of 10 (COLS) ints". Same as &array[2]
.
typedef
The function paramter list can be simplified by using a typedef. After define
ing 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 "a":
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.