Самые большие проблемы, связанные с назначением значений, возникают при попытке присвоить 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
Посмотрите вещи и дайте мне знать, если у вас есть дополнительные вопросы.