C - findMinMax in a 2D array - c

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!

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

I want to output 1 3 4 5 7 9 but I hardly stuck here

I have tried for two hours and cannot find the answer.
If someone can help I will be very thankful.
#include <stdio.h>
void somefunction(const int[], int);
int main() {
int a[] = { 1, 3, 4, 5, 7, 9, 11 };
somefunction(a, 5);
return 0;
}
void somefunction(const int b[], int c) {
if (c > 0) {
somefunction(b[], c - 1);
printf("%d ", b[c]);
}
}
if (c > 0) is the problem. You need to make it
if (c >= 0) to print the value of 1 inside a[0].
Also the first argument at the recursive call of somefunction inside somefunction needs to omit the [].
As additional hint, to print the value of 11 in a[6] you need to change
somefunction(a,5);
in main() to
somefunction(a,6);
The resuming code is this:
#include <stdio.h>
void somefunction(const int[], int);
int main() {
int a[] = { 1, 3, 4, 5, 7, 9, 11 };
somefunction(a,6);
return 0;
}
void somefunction(const int b[], int c) {
if (c >= 0) {
somefunction(b, c - 1);
printf("%d ", b[c]);
}
}
Output:
1 3 4 5 7 9 11

Array gets modified not int when called in a function

When I run this program-
#include <stdio.h>
void inc( int num[], int n)
{
int i;
n++;
for(i=0;i<10;i++)
num[i]++;
}
int main()
{
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
int a=2;
inc (arr, a);
int i;
for(i=0;i<10;i++)
printf("%d ", arr[i]);
printf("\n%d ", a);
return 0;
}
I get the output-
2 3 4 5 6 7 8 9 10 1
2
I understand why the int is unchanged but I don't understand why the array is getting changed since I have not used pointers to call the array. I know that the function will make a different copy of n and assign n=a and all changes will happen to n only and a will be unchanged. Why the array is getting changed?
In C, except for a few cases, an array name decays (=gets implicitly converted) to a pointer to its first element.
This
void inc(int num[], int n)
is exactly same as this:
void inc(int *num, int n)

Why does my Kadane's algorithm code give an output of 0 for all cases?

This is the code I wrote for finding the maximum sum subarray using Kadane's algorithm.
Code:
#include <stdio.h>
int maxSum(int a[],int size)
{
int ans=0; //stores the final sum
int sum=0; //stores the sum of the elements in the empty array
int i;
for(i=0;i<size;i++)
{
sum=sum+a[i];
if(sum<0)
{
sum=0;
}
if(ans<sum)
{
ans=sum;
}
}
return ans;
}
void main(){
int j,size,t,total; //size=size of the array,t=number of test cases
scanf("%d\n",&t);
while(t-->0)
{
int a[size];
for(j=0;j<size;j++)
{
scanf("%d ",&a[j]);
}
total=maxSum(a,size);
printf("\n%d",total);
}
}
I keep getting the wrong output:
For Input:
2 //test cases
3 //case 1
1 2 3
4 //case 2
-1 -2 -3 -4
Your Output is:
0 //it should be 6
0 //it should be -1
The only error is you haven't initialized size before using it to define the size of the array a - otherwise program is fine.
MAJOR--> It seems you are coding it on Turbo (as you have used void main() rather than int main(void)) which is an outdated compiler - shift to GCC or CLANG.

How to perform A-B set operation in C program using builtin library

I am new to C language. Suppose I have two arrays a and b
int a[10] = { 1,2,3,4,5,6,7,8,9,0 };
int b[10] = { 1,3,5,7,9 };
and I want to perform a-b so that I can get all elements of array a which are not present in array b. In ruby or python, I can just simply do a-b and get the result. Here is my c code that I have tried but my code which is not working.I am looking for a C library that does this operation for me in a line.I have also found this library but not sure how to implement it. Any kind of help is appreciated.
#include<stdio.h>
#define Max 100
int m,n,i,j,k,p,q,r,s;
int flag=1;
char char1,char2,char3;
void Difference(int *,int *,int ,int);
void Display2(char ,char ,int );
int a[10] = { 1,2,3,4,5,6,7,8,9,0 };
int b[10] = { 1,3,5,7,9 };
int c[10];
void Difference(int *a1,int *b1,int m1,int n1)
{
q=0;
p=0;
i=0;
for(k=0;k<m1;k++){
flag=1;
for(j=0;j<n1;j++){
if(b1[j]==a1[k]){
flag=1;
q++;
break;
}
else{
flag=0;
}
}
if(flag==0){
c[p]=a1[k];
p++;
}
}
}
void Display2(char ac,char bc,int m1)
{
printf("\nThe Difference Of Two Sets i.e '%c - %c' Is : { ",ac,bc);
r = m1 - q;
for(p=0;p<r;p++){
printf("%2d",c[p]);
}
printf(" }");
}
int main(){
Difference(a,b,m,n);
Display2('A','B',m);
return 0;
}
I can guess, you forgot to initialize your m and n variables with proper values.
Add m = 10; n = 5; before calling Difference and your code will work.
I also suggest you to write more readable code: better naming for variables, use some spaces and avoid global variables.
Edit:
In C++ you can write:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <set>
int main() {
std::set<int> a = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::set<int> b = { 1, 3, 5, 7, 9 };
std::set<int> c;
std::set_difference(a.begin(), a.end(), b.begin(), b.end(), std::inserter(c, c.begin()));
for (const auto item : c)
std::cout << item << " ";
return 0;
}
Detail information about std::set_difference can be found here

Passing arrays to a void function

I am trying to print out the contents of array1 times 10 if the integer inside is positive, if it is negative , the number should be left as it is in an another array. My code doesn't give me any result, I'm not that good in programming so I'm pretty sure I'm making a stupid mistake but I can't make out what it is, can someone point out the problem
void
tenfold (int array2[], int size )
{
int i, array1[size];
for (i=0;i<size;i++)
{
if (array1[i]>0)
array2[i]= 10 * array1[i];
else
array2[i]= array1[i];
}
}
int main()
{
int i,array1[9]= {3, 4, 5, 6, 7, -8, -9, 1, 2};
int size = 9;
tenfold(array1, size);
return 0;
}
tenfold should take array1 as input and array2 as local, other wise your are correct,
added a printf in tenfold to see the output.
#include<stdio.h>
void tenfold (int array1[], int size )
{
int i, array2[size];
for (i=0;i<size;i++)
{
if (array1[i]>0)
array2[i]= 10 * array1[i];
else
array2[i]= array1[i];
}
for(i=0;i<size;i++)
printf("(orignal) array1[%d]=%d, (new) array2[%d]=%d\n", i, array1[i], i, array2[i]);
}
int main()
{
int i,array1[9]= {3, 4, 5, 6, 7, -8, -9, 1, 2};
int size = 9;
tenfold(array1, size);
return 0;
}
Output:
(orignal) array1[0]=3, (new) array2[0]=30
(orignal) array1[1]=4, (new) array2[1]=40
(orignal) array1[2]=5, (new) array2[2]=50
(orignal) array1[3]=6, (new) array2[3]=60
(orignal) array1[4]=7, (new) array2[4]=70
(orignal) array1[5]=-8, (new) array2[5]=-8
(orignal) array1[6]=-9, (new) array2[6]=-9
(orignal) array1[7]=1, (new) array2[7]=10
(orignal) array1[8]=2, (new) array2[8]=20
You have changed the names of array in the function, update code to
//------------v array1
tenfold (int array1[], int size )
{
int i, array2[size]; //here array2
//your code
}
With your code, array1[] is never initialized and has random values, so if will not work as expected.
You should first start by trying to printf the values in tenfold(). :-)
You don't need to create array1 in tenfold().
Also, you may be able to get away from using a size variable and just use sizeof(array)/sizeof(array[0]).
tenfold doesn't print anything. There is no need to create another array if all you want if for that function to print. Be sure to add #include
#include <stdio.h>
void tenfold (int array[], int size)
{
int i;
for (i=0;i<size;i++)
{
if (array[i]>0)
printf("%d ", (10 * array[i]));
else
printf("%d ", array[i]);
}
}
output:
30 40 50 60 70 -8 -9 10 20

Resources