Home > Software engineering >  Value from array to array in C
Value from array to array in C

Time:12-19

I want to input an array, and then make 2 arrays, one contains odd elements of A and the other contains even elements. I calculated sum of all elements in those two arrays, but there was a problem like this. Can you explain for me pls?

#include <stdio.h>
void input(int x, int A[x]){
    for (int i = 0; i < x; i  ){
        printf("A[%d] = ", i);
        scanf("%d", &A[i]);
    }
}
int sum(int x, int A[x]){
    int s = 0;
    for (int i = 0; i < x; i  ){
        s  = A[i];
    }
    return s;
}
void OddnEven(int x, int A[x], int B[x], int C[x]){
    int m,n = 0;
    B[m] = 0;
    C[m] = 0;
    for (int i = 0; i < x; i  ){
        if(A[i] % 2 == 0){
            A[i] = B[m];
              m;
        } else {                
            A[i] = C[n];
              n;
        }
    } 
}
int main(){
    int x;
    printf("Enter size: "); scanf("%d", &x);
    int A[x], B[x], C[x];
    printf("Enter A: \n");
    input(x, A);
    printf("\nSum of all numbers in A:  %d", sum(x, A));
    OddnEven(x, A, B, C);
    printf("\nSum of even numbers in A: %d", sum(x, B));
    printf("\nSum of odd numbers in A: %d", sum(x, C));
}

Here is the output:

Enter size: 3
Enter A: 
A[0] = 1
A[1] = 2
A[2] = 3

Sum of all numbers in A:  6
Sum of even numbers in A: -1106957381
Sum of odd numbers in A: 423238244

CodePudding user response:

Problems in your code:

  • In OddnEven() function, the statement int m,n = 0; will only initialise n to 0 and m will be remain uninitialised and it is using variable m before initialising. The value of m is indeterminate and if you use it before initialising, it will lead to undefined behaviour. Instead, you should do int m = 0,n = 0;

  • In OddnEven() function, you are modifying the input array - A[i] = B[m];. It should be B[m] = A[i];. Same in else part of if block. May you should const modifier with the parameter int A[x], so that compiler flag these kind of issues.

  • In sum() function, you are adding all elements up to x and, due to this, your program end up accessing the array elements whose value is indeterminate. So, you should ensure that after filling up even numbers in array B and odd numbers in array C, rest of the elements of array B and C should be assigned 0. Or keep the record of number of even and odd elements in array B and C respectively.

  • In main() function, you should validate the user input size by adding upper and lower bounds check. Note that, array A, B and C are Variable Length Array (VLA). May you should try giving input size like a negative number or a huge positive number and check the program behaviour. Better to use some fixed size array like A[1024] and just add check whether the user input is > 0 and < 1024. The another advantage of using fixed size array is you can initialise it like this int A[1024] = {0};, which is not possible in case of VLA. If it's a need to have value of all elements of a VLA 0 before using it then you have to explicitly assign 0 to all elements of a VLA.

  • It is possible that sum of even numbers or odd numbers may overflow. You should check it and appropriately handle this situation.

Making the minimal required changes in your code:

#include <stdio.h>

void input(int x, int A[x]){
    for (int i = 0; i < x; i  ){
        printf("A[%d] = ", i);
        scanf("%d", &A[i]);
    }
}

int sum(int x, const int A[x]){
    int s = 0;
    for (int i = 0; i < x; i  ){
        s  = A[i];
    }
    return s;
}

void OddnEven(int x, const int A[x], int B[x], int C[x]){
    int m = 0, n = 0;

    for (int i = 0; i < x; i  ){
        if(A[i] % 2 == 0){
            B[m  ] = A[i];
        } else {                
            C[n  ] = A[i];
        }
    }
}

void init_arr(int size, int *arr) {
    while (size--) {
        arr[size] = 0;
    }
}

int main(){
    int x;

    printf("Enter size [1 - 100]: "); 
    scanf("%d", &x);

    //validate input size from user, add check for upper and lower bound
    //for e.g. input size should not be less than 0 and greater than 100

    if ((x < 1) || (x > 100)) {
        printf ("Invalid input, exiting..\n");
        //may you want to add retry logic here..
        return 0;
    }

    int A[x], B[x], C[x];

    printf("Enter A: \n");
    input(x, A);

    init_arr(x, B);
    init_arr(x, C);

    OddnEven(x, A, B, C);

    printf("Sum of all numbers in A:  %d\n", sum(x, A));
    printf("Sum of even numbers in B: %d\n", sum(x, B));
    printf("Sum of odd numbers in C: %d\n", sum(x, C));

    return 0;
}

Output:

Enter size [1 - 100]: 5
Enter A: 
A[0] = 10
A[1] = 15
A[2] = 20
A[3] = 25
A[4] = 30
Sum of all numbers in A:  100
Sum of even numbers in B: 60
Sum of odd numbers in C: 40

Leaving it up to you to try following:

  • Keeping record of number of even and odd elements in array B and C and in the sum function pass that as size to avoid the unnecessary loop iteration.

  • Check the overflow in sum() function and appropriately handle it.

  • At the time of taking input from user in array A identify whether the input number is even or odd, that way you have total number of even and odd elements in array A just after input from user. Declare B and C of type int * i.e. int pointer and allocate memory dynamically to them based on the even and odd number count. Make the other required changes in the program.

  • May you want to try with fixed size array as well once, like A[100], B[100] and C[100]. Initialise them like this int A[100] = {0}, B[100] = {0}, C[100] = {0};. Do other required changes in the program like keeping track of even and odd elements etc.

CodePudding user response:

This will happen because you are doing two wrong things in here

1st one is initiating arrays that have length x for B and C. But you don't update the values of that B and C from array A, instead of that, you are updating A from B and C. but B and C already have some garbage values. so when you add the values of A and B it adds garbage values, that is why you are getting these wrong values

2nd thing is, even if you put the values of A to B and C according to odd and even, you don't update all the values in B and C. Some indexes may update some are not, for that you need to initialize all the values of B and C something known value first (for example -1). then you can add all the values of B and C if the value is not equal to -1

You should not get -1 if you are using -1 to fill the array A, use something that you doesn't use to fill the array A

void OddnEven(int x, int A[x], int B[x], int C[x]){
   
    for (int i = 0; i < x; i  ){
        B[i] = -1
        C[i] = -1
        if(A[i] % 2 == 0){
            B[i] = A[i];
        } else {                
            C[i] = A[i];
        }
    } 
}

int sum(int x, int A[x]){
    int s = 0;
    for (int i = 0; i < x; i  ){
        if (A[i] != -1) {
          s  = A[i];
        }
    }
    return s;
}

CodePudding user response:

Consider making a support function that test for even/odd count.

int OddCount(int x, const int A[x]) {
  int count = 0;
  for (int i = 0; i < x; i  ) {
    if (A[i] % 2) count  ;
  }
  return count;
}

// Fix initialization.
void OddnEven(int x, const int A[x], int B[x], int C[x]) {
  // int m,n = 0; // Only sets n
  int m = 0,n = 0;
  ...
}

int main(){
  int x;
  printf("Enter size: "); scanf("%d", &x);
  int A[x];  // Only A
  printf("Enter A: \n");
  input(x, A);
  printf("\nSum of all numbers in A:  %d", sum(x, A));

  int odds = OddCount(x, A);
  int evens = x - odds;
  B[evens ? evens : 1] = 0; // Insure arrays have at least size 1 to prevent UB
  C[odds ? odds : 1] = 0;

  OddnEven(x, A, B, C);
  printf("\nSum of even numbers in A: %d", sum(evens, B));  // do not use x
  printf("\nSum of odd numbers in A: %d", sum(odds, C));
}
  •  Tags:  
  • c
  • Related