Как увеличить или уменьшить массив на языке C с помощью функции reallo c? - PullRequest
0 голосов
/ 06 апреля 2020

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

Но вместо этого он только изменяет массив локально и печатает его. Как я могу заставить ее вернуть массив и отменить ненужную печать?

Функция:

    void changeNumber(int *grades, int size)
    {

    int newSize = 0;
    int* newGrades = 0;
    int i = 0;

    printf("Enter new number of grades: ");
    scanf_s("%d", &newSize);

    if (newSize > size)
    {
        grades = (int*)realloc(grades, newSize * sizeof(int));
        for (i = size; i <= (newSize-1); i++)
        {
            printf("Enter grade %d: ", i+1);
            scanf_s("%d", grades+i);
            grades[i] = checkNumber(grades[i]); 
        }
        for (i = 0; i < newSize; i++)
        {
            printf("%d ", grades[i]);
        }
    }
    else if (newSize < size)
    {
        newGrades = (int*)malloc(newSize * sizeof(int));
        for (i = 0; i < (newSize-1); i++)
        {
            grades[i] = grades[i];
        }
        for (i = 0; i < newSize; i++)
        {
            printf("%d ", grades[i]);
        }
    }
    free(newGrades);

1 Ответ

0 голосов
/ 06 апреля 2020

Если тип возвращаемого значения функции void (вы не возвращаете новый pojnter в динамически распределенный массив), тогда вам нужно передать указатель на функцию по ссылке

void changeNumber(int **grades, int size);

В противном случае функция будет иметь дело с копией исходного аргумента и изменения копии не влияют на исходный аргумент.

Но так как функция устанавливает новый размер массива, то пользователь функции должен знать, что это новый размер массива. Так что вы должны, например, вернуть из функции новый размер массива.

int changeNumber(int **grades, int size);

Также, если новый выделенный массив имеет размер, который меньше текущего размера, тогда нет необходимости копировать элементы в сами

    newGrades = (int*)malloc(newSize * sizeof(int));
    for (i = 0; i < (newSize-1); i++)
    {
        grades[i] = grades[i];
    }

И вам нужно присвоить новый указатель старому указателю на первый элемент массива.

Вместо типа int, используемого для размера массива, он является гораздо лучше использовать целое число без знака size_t.

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

size_t changeNumber( int **grades, size_t size )
{
    size_t newSize = 0;

    printf( "Enter new number of grades: " );

    if ( scanf( "%zu", &newSize ) == 1 && size != newSize )
    {
        int *newGrades = realloc( *grades, newSize * sizeof( int ) );

        if ( newGrades != NULL )
        {
            if ( size < newSize )
            {
                for ( size_t i = size; i < newSize; i++ )
                {
                    printf( "Enter grade %zu: ", i + 1 );
                    scanf("%d", newGrades + i );
                    newGrades[i] = checkNumber( newGrades[i] ); 
                }
            }

            size = newSize;
            *grades = newGrades; 
        }
    }

    for ( size_t i = 0; i < size; i++ )
    {
        printf( "%d ", ( *grades )[i] );
    }
    putchar( '\n' );

    return size;   
}

Обратите внимание на тот указатель, который косвенно передается в функцию через указатель на него в качестве аргумента также должен указывать на динамически размещаемый массив.

...