копипаста из двух массивов в третий

стоит задача: Сформировать новый упорядоченный по убыванию массив из двух упорядоченных в том же порядке массивов: А (12) и В (20). Задача вроде бы не сложная, но на ней я запутался.. Написал код(специально уменьшил размеры массива, чтобы легче было проверять):

#include<stdio.h>
#include<stdlib.h>
int main()
{
    int a[4], b[5],c[9];
    int* pa = &a[0], *pc=&c[0], *pb = &b[0];
    int i = 0, k = 0, m = 0, j = 0, g = 0, f = 0;

    printf("Заполните массив a: \n");
    for (i = 0; i < 4; i++)
        scanf("%d", &a[i]);
    for (i = 0; i < 4; i++)
        for (m = i + 1; m < 4; m++)
            if (a[i] < a[m])
            {
                k = *(pa + i);
                *(pa + i) = *(pa + m);
                *(pa + m) = k;
            }
    for (i = 0; i < 4; i++)
        printf("%d ", a[i]);
    printf("\n");

    printf("Заполните массив b: \n");
    for (j = 0; j < 5; j++)
        scanf("%d ", &b[j]);
    for (j = 0; j < 5; j++)
        for (g = j + 1; g < 5; g++)
            if (b[j] < b[g])
            {
                f = *(pb + j);
                *(pb + j) = *(pb + g);
                *(pb + g) = f;
            }
    for (j = 0; j < 5; j++)
        printf("%d ", b[j]);
    printf("\n");    
    for (i=0, k=0; i<4;i++){
        c[k++]=a[i];
    }
    for (i=0, k=0; i<5;i++){
        c[k++]+=b[i];
    }
    for (j = 0; j < 9; j++)
        printf("%d ", c[j]);
    return 0;
}

Но все остановилось на том, что, во-первых, после ввода, в моем случае, 5 значений массива b, программа ждет ввода еще одного значения, а после выдает отсортированный массив b. Сначала думал, что это ошибка компилятора, но перейдя на онлайн компилятор - ошибка осталась. Но основная загвоздка в том, что я не могу, а точнее просто не знаю, как отсортированные значения массивов переписать в новый, и уже в нем их так же расставить по порядку. Серфил в поисках ответа, но так ничего не нашел. Буду рад вашим ответам и подсказкам! p.s. также хотелось бы попросить у вас рекомендации о какой-нибудь книжке по программированию на си(сам, что видно по коду, пока начинающий).


Ответы (2 шт):

Автор решения: MBo

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

Использование магических чисел неправильно, поэтому приведу общую реализацию с длинами массивов alen и blen

 ia = 0;
 ib = 0;
 ic = 0;
 while (ia < alen && ib < blen) {
     if (a[ia] >= b[ib])
        c[ic++] = a[ia++];
     else
        c[ic++] = b[ib++];
 }
 //если в одном из массивов остались элементы, докопируем
 while (ia < alen) 
    c[ic++] = a[ia++];
 while (ib < blen) 
    c[ic++] = b[ib++];
→ Ссылка
Автор решения: MiniMax
  1. Чтобы меньше путаться надо выносить участки кода в функции, это упростит код и устранит дублирование (как в случае с написаной несколько раз сортировкой в вашем коде). Также важно давать переменным осмысленные имена.
  2. При правильном подходе массив полученный в результате слияния двух отсортированных массивов не требует сортировки - значения становятся на нужные места при слиянии - за один проход. Это оптимальнее дополнительной сортировки.

Моё решение. Значения отсортированны по возрастанию.

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

void merge_two_sorted_arrs(size_t size1, int arr1[],
                           size_t size2, int arr2[],
                           size_t size3, int arr3[]) {
    size_t c1 = 0;
    size_t c2 = 0;
    for(size_t c3 = 0; c3 < size3; c3++) {
        if ((c2 >= size2) || (c1 < size1 && arr1[c1] < arr2[c2]))
            arr3[c3] = arr1[c1++];
        else
            arr3[c3] = arr2[c2++];
    }
}

void sort_arr(size_t size, int arr[size]) {
    for(size_t i = 0; i < size; i++) {
        for(size_t j = 1; j < size - i; j++) {
            if (arr[j - 1] > arr[j]) {
                int tmp = arr[j];
                arr[j] = arr[j - 1]; 
                arr[j - 1] = tmp; 
            }
        }
    }
}

void fill_arr_by_rand(size_t size, int arr[size]) {
    for(size_t i = 0; i < size; i++) {
        arr[i] = rand() % 10;   
    }
}

void print_arr(size_t size, int arr[size]) {
    for(size_t i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    puts("\n");
}

int main() {
    srand(time(NULL));

    size_t size1, size2;

    puts("Enter arr1 size: ");
    scanf("%zu", &size1);

    puts("Enter arr2 size: ");
    scanf("%zu", &size2);

    size_t size3 = size1 + size2;
    int arr1[size1];
    int arr2[size2];
    int arr3[size3];

    fill_arr_by_rand(size1, arr1);

    puts("Filled arr1");
    print_arr(size1, arr1);

    sort_arr(size1, arr1);

    puts("Sorted arr1");
    print_arr(size1, arr1);

    fill_arr_by_rand(size2, arr2);

    puts("Filled arr2");
    print_arr(size2, arr2);

    sort_arr(size2, arr2);

    puts("Sorted arr2");
    print_arr(size2, arr2);


    merge_two_sorted_arrs(size1, arr1, size2, arr2, size3, arr3);
    puts("Merged arr3");
    print_arr(size3, arr3);

    return 0;
}

Тест

$ gcc merge_two_sorted_arrays.c
$ echo -n 4 5 | ./a.out

Enter arr1 size: 
Enter arr2 size: 
Filled arr1
5 6 3 3 

Sorted arr1
3 3 5 6 

Filled arr2
4 3 6 2 2 

Sorted arr2
2 2 3 4 6 

Merged arr3
2 2 3 3 3 4 5 6 6 
→ Ссылка