Динамический массив: разделение чисел на четные и нечетные с помощью C - PullRequest
1 голос
/ 22 мая 2019

Моя программа должна сначала запросить число целых чисел для чтения и динамически выделить массив, достаточно большой, чтобы вместить количество значений, которые я прочитал.Затем мне нужно разделить эти значения на нечетные и четные.

Это код, который я пробовал

#include <stdio.h> 
#include <stdlib.h>
int main(void){

//declare variables
int i; //loop counter
int count; //integer amount from user
int j = 0; int k = 0;

// read in integer count from user
printf("enter the amount of numbers: ");
scanf("%d", &count);

// declare pointer 
int *number = malloc(sizeof(int)*count);
int *evens = malloc(sizeof(int)*count);
int *odds = malloc(sizeof(int)*count);

// declare variable
//int odds_count = 0;
//int evens_count = 0;

//loop to read in numbers from user
for (i=0; i<count; i++){
    printf("enter number %02d: ",i+1);
    scanf("%d",(number+i));
    printf("you entered %d\n", *(number+i)); //--- entered values are correct here
    if (*(number+i)% 2 ==0){
        *(number+i) = *(evens+j);
        j++;
        //evens_count++;
    } else {
        *(number+i) = *(odds+k);
        k++;
    }
    printf("you entered %d\n", *(number+i));  //---entered values become 0
}
//print array elements
printf("\nEntered array elements are:\n");
for(i=count;i>0;i--)
{
    printf("%d ",*(number+i));
}
printf("\n");

// print out even numbers
printf("even numbers: ");
for (i=0;i<j;i++){
    printf("%5d",*(evens+i));
}
printf("\n");

// print out odd numbers
printf("odd numbers: ");
for (i=0;i<k;i++){
    printf("%5d",*(odds+i));
}
printf("\n");

return 0;
}

Независимо от того, какой ввод я ввожу, вывод показывает только 0. Например:

Input- 1, 2, 3
Output-
Evens: 0
Odds: 0 0

Пожалуйста, помогите мнес этим.Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 22 мая 2019

Самые большие проблемы, связанные с назначением значений, возникают при попытке присвоить evens[j] и odds[j] numbers[i] до инициализации элементов evens или odds. После вашего вызова malloc для каждого evens и odds выделенный блок памяти содержит все значения мусора, которые находятся в этой области памяти во время выделения. malloc никоим образом не инициализирует содержимое памяти и оставляет значения неопределенными. Если вы хотите выделить и обнулить все байты, вы можете использовать calloc вместо malloc.

Эта проблема возникает здесь:

    if (*(number+i)% 2 ==0){
        *(number+i) = *(evens+j);
        j++;
        //evens_count++;
    } else {
        *(number+i) = *(odds+k);
        k++;
    }

Посмотрите внимательно, вы проверяете, является ли numbers[i] четным / нечетным с % 2 == 0, но затем пытаетесь перезаписать значение на numbers[i] с помощью evens[j] или odds[k] - , это наоборот . Намерением будет присвоить значение в numbers[i] либо evens[j], либо odds[k], например,

    if (number[i] % 2 ==0){
        evens[j] = number[i];
        j++;
        //evens_count++;
    } else {
        odds[k] = number[i];
        k++;
    }

Далее, вы используете переменные беспорядочно. Вам не нужны все различные i, j, k счетчики, объявленные в начале main(). За последние 20 лет, начиная с C99, вы можете объявить переменную цикла в самом объявлении цикла for. Это исключает вероятность того, что использование вами переменной цикла будет конфликтовать с другим использованием i, j, k в другом месте программы.

У вас есть count, odd_count & even_count, это единственные счетчики, которые вам нужны.

Далее, вам нужно VALIDATE каждый пользовательский ввод и каждый распределение. В противном случае вы рискуете вызвать Неопределенное поведение с быстрым нажатием клавиши или когда (не «если») распределение возвращает NULL. Проверяйте каждый критический шаг.

Применяя эти меры, вы можете упростить вашу декларацию до:

    int count,          /* integer amount from user     */
        odd_count = 0,  /* odd count (initialized zero) */
        even_count = 0, /* even count (initialized zero)*/
        *number,        /* declare pointers             */
        *evens,
        *odds; 

Вы можете подтвердить ввод с помощью:

    /* read in integer count from user (VALIDATE every input) */
    printf("enter the amount of numbers: ");
    if (scanf("%d", &count) != 1) {
        fputs ("error: invalid integer input.\n", stderr);
        return 1;
    }
    ...
    for (int i = 0; i < count; i++) {   /* loop count times for input */
        printf ("enter number %2d: ", i + 1);
        if (scanf ("%d", &number[i]) != 1) {    /* validate EVERY input */
            fputs ("error: invalid integer input.\n", stderr);
            return 1;
        }
        if (number[i] % 2 == 0)     /* assign, increment evens count */
            evens[even_count++] = number[i];
        else                        /* same for odds */
            odds[odd_count++] = number[i];
    }

И вы можете подтвердить свои ассигнования:

    /* allocate count integers each pointer (VALIDATE every allocation) */
    if ((number = malloc (count * sizeof *number)) == NULL) {
        perror ("malloc-number");
        return 1;
    }
    if ((evens = malloc (count * sizeof *evens)) == NULL) {
        perror ("malloc-evens");
        return 1;
    }
    if ((odds = malloc (count * sizeof *odds)) == NULL) {
        perror ("malloc-odds");
        return 1;
    }

Тогда просто нужно зациклить i = 0; i < count для вывода number, i = 0; i < even_count для вывода evens и, наконец, i = 0; i < odd_count для вывода odds, например,

    puts ("\n numbers\n--------");      /* output each array on its own */
    for (int i = 0; i < count; i++)
        printf ("%8d\n", number[i]);

    puts ("\n   evens\n--------");
    for (int i = 0; i < even_count; i++)
        printf ("%8d\n", evens[i]);

    puts ("\n    odds\n--------");
    for (int i = 0; i < odd_count; i++)
        printf ("%8d\n", odds[i]);

И, наконец, вы можете вывести все 3 массива одновременно с помощью:

    /* output all arrays together */
    puts ("\nnumbers      even      odd\n-------- -------- --------");
    for (int i = 0; i < count; i++) {       /* loop printing number */
        printf ("%8d", number[i]);
        if (i < even_count) {               /* if i < even_count */
            printf (" %8d", evens[i]);      /* output evens */
            if (i < odd_count)              /* if odds too, output them */
                printf (" %8d\n", odds[i]);
            else
                putchar ('\n');             /* no more odds output '\n' */
        }
        else if (i < odd_count)             /* if only odds left, output */
            printf ("%18d\n", odds[i]);
        else
            putchar ('\n');
    }

В конце не забудьте освободить выделенную память, например,

    free (number);  /* don't forget to free what you allocated */
    free (evens);
    free (odds);

В целом, вы можете сделать:

#include <stdio.h> 
#include <stdlib.h>

int main(void) {

    int count,          /* integer amount from user     */
        odd_count = 0,  /* odd count (initialized zero) */
        even_count = 0, /* even count (initialized zero)*/
        *number,        /* declare pointers             */
        *evens,
        *odds; 

    /* read in integer count from user (VALIDATE every input) */
    printf("enter the amount of numbers: ");
    if (scanf("%d", &count) != 1) {
        fputs ("error: invalid integer input.\n", stderr);
        return 1;
    }

    /* allocate count integers each pointer (VALIDATE every allocation) */
    if ((number = malloc (count * sizeof *number)) == NULL) {
        perror ("malloc-number");
        return 1;
    }
    if ((evens = malloc (count * sizeof *evens)) == NULL) {
        perror ("malloc-evens");
        return 1;
    }
    if ((odds = malloc (count * sizeof *odds)) == NULL) {
        perror ("malloc-odds");
        return 1;
    }

    for (int i = 0; i < count; i++) {   /* loop count times for input */
        printf ("enter number %2d: ", i + 1);
        if (scanf ("%d", &number[i]) != 1) {    /* validate EVERY input */
            fputs ("error: invalid integer input.\n", stderr);
            return 1;
        }
        if (number[i] % 2 == 0)     /* assign, increment evens count */
            evens[even_count++] = number[i];
        else                        /* same for odds */
            odds[odd_count++] = number[i];
    }

    puts ("\n numbers\n--------");      /* output each array on its own */
    for (int i = 0; i < count; i++)
        printf ("%8d\n", number[i]);

    puts ("\n   evens\n--------");
    for (int i = 0; i < even_count; i++)
        printf ("%8d\n", evens[i]);

    puts ("\n    odds\n--------");
    for (int i = 0; i < odd_count; i++)
        printf ("%8d\n", odds[i]);

    /* output all arrays together */
    puts ("\nnumbers      even      odd\n-------- -------- --------");
    for (int i = 0; i < count; i++) {       /* loop printing number */
        printf ("%8d", number[i]);
        if (i < even_count) {               /* if i < even_count */
            printf (" %8d", evens[i]);      /* output evens */
            if (i < odd_count)              /* if odds too, output them */
                printf (" %8d\n", odds[i]);
            else
                putchar ('\n');             /* no more odds output '\n' */
        }
        else if (i < odd_count)             /* if only odds left, output */
            printf ("%18d\n", odds[i]);
        else
            putchar ('\n');
    }

    free (number);  /* don't forget to free what you allocated */
    free (evens);
    free (odds);
}

Пример использования / вывода

$ ./bin/number_evens_odds
enter the amount of numbers: 10
enter number  1: 21
enter number  2: 22
enter number  3: 23
enter number  4: 24
enter number  5: 119
enter number  6: 121
enter number  7: 131
enter number  8: 140
enter number  9: 141
enter number 10: 143

 numbers
--------
      21
      22
      23
      24
     119
     121
     131
     140
     141
     143

   evens
--------
      22
      24
     140

    odds
--------
      21
      23
     119
     121
     131
     141
     143

numbers      even      odd
-------- -------- --------
      21       22       21
      22       24       23
      23      140      119
      24               121
     119               131
     121               141
     131               143
     140
     141
     143

Посмотрите вещи и дайте мне знать, если у вас есть дополнительные вопросы.

0 голосов
/ 22 мая 2019

Получая ввод от пользователя, попробуйте поставить символ '&' перед именем вашей переменной. Я думаю, что это должно сработать.

scanf("%d",&(number+i));

Удачного кодирования:)

...