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.