Home > Software engineering >  C - findMinMax in a 2D array
C - findMinMax in a 2D array

Time:11-08

I have recently started learning coding in C. The function is to extract the min and max value from the 2D array. I cannot understand why version #1 works but not version #2 (The difference being "else if" or "if" is used)

The specific test case that I used is:

1 2 -3 4 5
2 3 4 5 6
4 5 6 7 8
5 4 23 1 27
1 2 3 4 5

Version #1

#include <stdio.h>
#define SIZE 5
void findMinMax2D(int ar[SIZE][SIZE], int *min, int *max);
int main()
{
    int A[5][5];
    int i,j,min,max;

    printf("Enter the matrix data (%dx%d): \n",SIZE,SIZE);
    for (i=0;i<5;i  )
        for (j=0;j<5;j  )
            scanf("%d",&A[i][j]);
    findMinMax2D(A,&min,&max);
    printf("min = %d\nmax=%d",min,max);
    return 0;
}

void findMinMax2D(int ar[SIZE][SIZE], int *min, int *max)
{

int row,col;
   (*min)=ar[0][0];
   (*max)=ar[0][0];
   for (row=0;row<SIZE;row  )
   {
       for (col=0;col<SIZE;col  )
           if (ar[row][col]>(*max))
           {
               (*max)=ar[row][col];
           }
           else if (ar[row][col]<(*min)) //else if works here
           {
               (*min)=ar[row][col];
           }  
   }

}

This gives me min = -3 and max = 27

Version #2

#include <stdio.h>
#define SIZE 5
void findMinMax2D(int ar[SIZE][SIZE], int *min, int *max);
int main()
{
    int A[5][5];
    int i,j,min,max;

    printf("Enter the matrix data (%dx%d): \n",SIZE,SIZE);
    for (i=0;i<5;i  )
        for (j=0;j<5;j  )
            scanf("%d",&A[i][j]);
    findMinMax2D(A,&min,&max);
    printf("min = %d\nmax=%d",min,max);
    return 0;
}

void findMinMax2D(int ar[SIZE][SIZE], int *min, int *max)
{

int row,col;
   (*min)=ar[0][0];
   (*max)=ar[0][0];
   for (row=0;row<SIZE;row  )
   {
       for (col=0;col<SIZE;col  )
           if (ar[row][col]>(*max))
           {
               (*max)=ar[row][col];
           }
           if (ar[row][col]<(*min)) //if does not work here
           {
               (*min)=ar[row][col];
           }  
   }

}

This gives me min = 1 and max = 27

where I cannot get -3 to be extracted in version 2. To my knowledge, the use of "else if" or "if" in this scenario is inconsequential. Any advice is greatly appreciated, thank you!

CodePudding user response:

I fixed the compiler errors in the code and replaced the input with hard-coded example data:

#include <stdio.h>
#define SIZE 5
void findMinMax2D(int ar[SIZE][SIZE], int *min, int *max);
int main()
{
    int A[5][5] = {
        { 1, 2, -3, 4, 5 },
        { 2, 3, 4, 5, 6 },
        { 4, 5, 6, 7, 8 },
        { 5, 4, 23, 1, 27 },
        { 1, 2, 3, 4, 5 }
    };
    
    int min,max;

    findMinMax2D(A,&min,&max);
    printf("min = %d\nmax=%d",min,max);
    return 0;
}

void findMinMax2D(int ar[SIZE][SIZE], int *min, int *max)
{

int row,col;
   (*min)=ar[0][0];
   (*max)=ar[0][0];
   for (row=0;row<SIZE;row  )
   {
       for (col=0;col<SIZE;col  )
           if (ar[row][col]>(*max))
           {
               (*max)=ar[row][col];
           }
           if (ar[row][col]<(*min)) //else if works here
           {
               (*min)=ar[row][col];
           }  
   }

}

When I compile this with GCC, I get these warnings:

main.c: In function ‘findMinMax2D’:
main.c:29:8: warning: this ‘for’ clause does not guard... [-Wmisleading-indentation]
   29 |        for (col=0;col<SIZE;col  )
      |        ^~~
main.c:34:12: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the ‘for’
   34 |            if (ar[row][col]<(*min)) //else if works here
      |            ^~

When you run your code step-by-step in a debugger you will see that the second if does not get executed inside the loop.

The problem is caused by missing braces at the for.

The if...else is a single statement which does not need braces. (It is irrelevant that the else branch contains another if statement.)

Without else you have two individual if statements, and despite the misleading indentation, only the first one is in the for loop's body. The second if will be executed after the end of the for loop leading to an out-of-bounds access to the array.

The fix is

       for (col=0;col<SIZE;col  )
       { /* <-------------------------------- *** important ***/
           if (ar[row][col]>(*max))
           {
               (*max)=ar[row][col];
           }
           if (ar[row][col]<(*min))
           {
               (*min)=ar[row][col];
           }  
       } /* <-------------------------------- *** important ***/

This is the reason why coding rules for safety-critical software often require to use braces even with a simple single statement where C would not require braces.

  • Related