Home > front end >  0 in The Array is Causing a Semantic Error. How to Overcome?
0 in The Array is Causing a Semantic Error. How to Overcome?

Time:12-23

The question is to make a program to read an integer array from the user and pass it to a function that takes two arrays - the first array with the values obtained form the user and the second array as an empty array. The objective is to append the indices of the even numbers present in the original array to the empty array and return the number of even numbers present in the original array.

If the input was:

Enter number of elements: 5
Enter element [1]: 0
Enter element [2]: 1
Enter element [3]: 2
Enter element [4]: 3
Enter element [5]: 4

Then the output shows:

37945345.

which is a garbage value inside the empty array's first element.

This is the code:

#include <stdio.h>

int evenIndices(int origArr[], int emptyArr[]) {

    int i = 0, j = 0;
    int evenCount = 0;

    while (origArr[i] != '\0') {
        if (origArr[i] % 2 == 0) {
            emptyArr[j] = i;
            evenCount   ;
            j  ;
        }
        i  ;
    }

    return evenCount;
}

int main() {

    int numOfElts;
    printf("Enter number of elements: ");
    scanf("%d", &numOfElts);
    int arr[numOfElts];

    for (int i = 0; i < numOfElts; i  ) {
        printf("Enter element [%d]: ", i   1);
        scanf("%d", &arr[i]);
    }

    arr[numOfElts] = '\0';

    int indexArr[numOfElts];
    int evenCount = evenIndices(arr, indexArr);

    printf("There are %d even numbers. \n", evenCount);
    printf("*** Indices With Even Numbers in Original Array *** \n");

    for (int i = 0; i < evenCount - 1; i  ) {
        printf("%d, ", indexArr[i]);
    }

    printf("%d. \n", indexArr[evenCount - 1]);

    return 0;
}

This code works for all numbers in array except for 0. If 0 is entered, the function assumes that it is same as '\0' and quits the loop. What is the solution to this?

CodePudding user response:

"pass it to a function that takes two arrays"

To pass arrays, the size information must be included in some way as array parameters in C decay into simple pointers, losing all array size information. The following method makes use of the VLA parameter format, i.e. define the size(s) of the array(s) you are passing prior to the array(s) themselves in the prototype...

Change the prototype from:

int evenIndices(int origArr[], int emptyArr[]);

To:

int evenIndices(int x, int y, int origArr[x], int emptyArr[y]);

Then pass it as:

int evenCount = evenIndices(numOfElts, numOfElts, arr, indexArr);

Or, because the size of both arrays sizes in this case are the same, you can use define only int x in the prototype,

 int evenIndices(int x, int origArr[x], int emptyArr[x]);

then pass it as:

 int evenCount = evenIndices(numOfElts, origArr, emptyArr);

CodePudding user response:

For starters this assignment statement

arr[numOfElts] = '\0';

invokes undefined behavior because there is an access of memory beyond the array because the valid range of indices for the array is [0, numOfElts).

Remove this statement.

The function evenIndices should be declared like

int evenIndices( const int origArr[], int n, int emptyArr[]);

That is you need to pass the number of elements in the original array. And the first parameter should be declared with the qualifier const because the passed array is not changed within the function.

The condition in the while loop

while (origArr[i] != '\0') {

does not make a sense. The user can enter 0 as a valid value of the source array.

One of these variables, j and evenCount, is redundant.

The function can be defined the following way

int evenIndices( const int origArr[], int n, int emptyArr[])
{
    int evenCount = 0;
    
    for ( int i = 0; i < n; i   )
    {
        if ( origArr[i] % 2 == 0 ) emptyArr[evenCount  ] = i;
    }

    return evenCount;
}      

And the function is called like

int evenCount = evenIndices( arr, numOfElts, indexArr );

Pay attention to that if the function returns 0 then this code snippet

for (int i = 0; i < evenCount - 1; i  ) {
    printf("%d, ", indexArr[i]);
}

printf("%d. \n", indexArr[evenCount - 1]);

will produce an invalid output. There is no need to split the for loop. Instead write

for (int i = 0; i < evenCount; i  ) {
    printf("%d, ", indexArr[i]);
}

putchar( '\n' );

CodePudding user response:

You are trying to use '\0' as a sentinel. Thus you cannot have '\0' or '0' ('\0' is 0) as a valid value. I would recommend that you use INT_MIN as the sentinel. Then your range of acceptableinputs will be 2^32-1 to -(2^32-1) and that will be nice.

  • Related