-1

I was asked to define a function takes in the values of a list and distributes its elements into two lists: one meant for the odd numbers and the other for the even. I have created the function array_oddeven() and passed it two parameters:

int *ptr : a pointer to the array

int length : represents the size of the array

and called it inside int main()

This is my code :

#include <stdio.h>
#include <stdlib.h>
#define UPPER_BOUND 8
#define MAX  100
#define SIZE  12

void array_print(int *ptr, int length) {
    for (int i = 0; i < length; i++) {
        printf("%d ", ptr[i]);
    }
    printf("\n");
}

int* array_create(int length) {
    int *t = (int*)malloc(length * sizeof(int));
    for (int i = 0; i < length; i++) {
        t[i] = rand() % MAX;
    }

    return t;
}

int *array_oddeven(int *ptr, int length){
    int *even = (int*)malloc(length * sizeof(int));
    int *odd = (int*)malloc(length * sizeof(int));
    int j=0;
    int k=0;
    for (int i = 0; i < length; i++)
    {
        if (ptr[i] % 2 == 0) {
            even[j] = ptr[i];
            j++;
        } else {
            odd[k] = ptr[i];
            k++;
        }
    } 
    return even, odd;
}

int main()
 {
    int *t = array_create(SIZE);
    int *even = array_oddeven(t, SIZE);
    int *odd = array_oddeven(t, SIZE);
    array_print(t, SIZE);
    array_print(even, SIZE);
    array_print(odd, SIZE);
    free(odd);
    free(even);
    free(t);
    return 0;
}

I was expecting this result :

83 86 77 15 93 35 86 92 49 21 62 27 
83 77 15 93 35 49 21 27 
86 86 92 62

But I got this output instead :

83 86 77 15 93 35 86 92 49 21 62 27 
83 77 15 93 35 49 21 27 0 0 0 0 
83 77 15 93 35 49 21 27 0 0 0 0 

Where is my mistake?

3 Answers3

3

As pointed in comment, your code does not do what you probably think: return even, odd; uses the comma operator What does the comma operator , do?

As a matter of fact it does not return both values, but only one.

If you want to retrieve both arrays, you may pass return values as input parameter of you function; this my look like:

void array_oddeven(const int *ptr, int length, int **podd, int **peven){
    /* fill both arrays with 0 as your print function go thru the whole
     * lenght of elements */
    int *even = calloc(length, sizeof(int));
    int *odd = calloc(length, sizeof(int));
    int j=0;
    int k=0;
    for (int i = 0; i < length; i++)
    {
        if (ptr[i] % 2 == 0) {
            even[j] = ptr[i];
            j++;
        } else {
            odd[k] = ptr[i];
            k++;
        }
    }
    *peven = even;
    *podd = odd;
}

int main()
 {
    int *t = array_create(SIZE);
    int *even;
    int *odd;
    array_oddeven(t, SIZE, &odd, &even);
    array_print(t, SIZE);
    array_print(even, SIZE);
    array_print(odd, SIZE);
    free(odd);
    free(even);
    free(t);
    return 0;
}

Worth noticing that you then return arrays of "unknown" size as you know little about number of even/odd elements, thus you could probably pass the output number of elements in the same way:

void array_oddeven(const int *ptr, int length, int **podd, size_t *poddnumelts,
                                               int **peven, size_t *pevennumelts) {
    /* malloc is back here as the array does not require to be filled with
     * zeros as we return the number of elements that were set */
    int *even = malloc(length * sizeof(int));
    int *odd = malloc(length * sizeof(int));
    int j = 0;
    int k = 0;
    for (int i = 0; i < length; i++)
    {
        if (ptr[i] % 2 == 0) {
            even[j] = ptr[i];
            j++;
        } else {
            odd[k] = ptr[i];
            k++;
        }
    }
    *peven = even;
    *pevennumelts = j;
    *podd = odd;
    *poddnumelts = k;
}

int main()
 {
    int *t = array_create(SIZE);
    int *even, *odd;
    size_t oddnumelts, evennumelts;
    array_oddeven(t, SIZE, &odd, &oddnumelts, &even, &evennumelts);
    array_print(t, SIZE);
    array_print(even, evennumelts);
    array_print(odd, oddnumelts);
    free(odd);
    free(even);
    free(t);
    return 0;
}

In a more general way, you can consider that having an array passed without its size to a function can be considered as fishy (in C) as there is no way of "guessing" it later, thus a "normal" API would always ask the array and its size.

OznOg
  • 4,440
  • 2
  • 26
  • 35
  • This worked great, however could you explain me how do I get rid of the zeros that come after the sorted elements please? –  Nov 17 '18 at 19:29
0

Functions in C return only one thing and since the comma operator discards the left operand after evaluating it then evaluates the right operand and considers it the result, you are basically only returning the odd array here.

Islam Hassan
  • 673
  • 1
  • 10
  • 21
0
 #include <stdio.h>
#include <stdlib.h>
#define UPPER_BOUND 8
#define MAX  100
#define SIZE  12
int counteven,countodd;
void array_print(int *ptr, int length) {
    for (int i = 0; i < length; i++) {
        printf("%d ", ptr[i]);
    }
printf("\n");
}

int* array_create(int length) {
int *t = (int*)malloc(length * sizeof(int));
for (int i = 0; i < length; i++) {
    t[i] = rand() % MAX;
   }

return t;
}

int *array_oddeven(int *ptr, int length){
int j=0;
int k=0;
for (int i = 0; i < length; i++)
{
    if (ptr[i] % 2 == 0) {
       counteven++;
    } else {
        countodd++;
    }
}
int *even,*odd;
even = (int*)malloc(counteven * sizeof(int));
odd = (int*)malloc(countodd * sizeof(int));
for (int i = 0; i < length; i++)
{
    if (ptr[i] % 2 == 0) {
       *(even+j)=ptr[i];
       j++;
    } else {
        *(odd+k)=ptr[i];
        k++;
    }
}
array_print(odd, countodd);
array_print(even, counteven);
}

int main()
{
int *t = array_create(SIZE);
int *even;
int *odd;
array_print(t, SIZE);
array_oddeven(t, SIZE);
free(odd);
free(even);
free(t);
return 0;
}

`