Как изменить размер массива и вставить другой элемент? - PullRequest
0 голосов
/ 06 мая 2020

У меня есть массив 0 1 2 4 5 6 7 8 9. Я хочу вставить 3 между 2 и 4.

Длина остается неизменной после вызова функции, хотя я добавил значение, почему?

printf("%d,", feld[9]); дает мне правильное значение, код работает, но я получаю предупреждение.

Как мне вставить значение, даже если я инициализирую int feld[9] = {0,1,2,4,5,6,7,8,9}; или int feld[] = {0,1,2,4,5,6,7,8,9};?


nt insertArray(int* array, int length, int value, int pos) 
{
    int i;

    if (pos < length)
    {
        for (i = length; i > pos; i--)
        {
            array[i] = array[i - 1];
        }
        array[i] = value;
        length++;
    }

    else if (pos == length)
    {
        array[pos] = value;
        length++;
    }
    return length;
}


int main()
{
    int feld[9] = {0,1,2,4,5,6,7,8,9};

    size_t length = sizeof(feld) / sizeof(int);

    insertArray(feld, length, 3, 3);

    length = sizeof(feld) / sizeof(int);

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

    printf("%d,", feld[9]);

    return 0;
}

Ответы [ 3 ]

1 голос
/ 06 мая 2020

Per C синтаксис. Не разрешается изменять длину статического c массива после его определения. Любая попытка сделать это вызывает неопределенное поведение .

Вместо этого выделите динамическую c память с помощью malloc(), используйте смещения указателя для доступа к определенным псевдоэлементам и используйте realloc() для изменения размера память.

Скопируйте содержимое элементов 4 в 9 в элементы 5 в 10. Теперь вы можете сохранить 3 в элементе 4th.

Один наглядный пример:

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

#define SIZE 9
#define ELEM_TO_CH 4

int main(void)
{
    int* feld_ptr = malloc(sizeof(int) * SIZE);
    if(!feld_ptr)
    {
       fprintf(stderr,"Memory could not be allocated for feld_ptr!");
       return 1;
    }

    for(int i = 0; i < SIZE; i++)
    {
       if (i > (ELEM_TO_CH - 2))
          feld_ptr[i] = i + 1;
       else
          feld_ptr[i] = i;
    }

    printf("Before:\n\n");
    for(int i = 0; i < SIZE; i++)
    {
       printf("feld_ptr[%d] = %d\n", i, feld_ptr[i]);
    }

    printf("\n\n");

    feld_ptr = realloc(feld_ptr, SIZE + 1);
    if(!feld_ptr)
    {
       fprintf(stderr,"Error at resizing memory pointed by feld_ptr!");
       return 1;
    }

    memcpy(&feld_ptr[ELEM_TO_CH], &feld_ptr[ELEM_TO_CH-1], sizeof(int) * ((SIZE + 1) - ELEM_TO_CH));

    feld_ptr[ELEM_TO_CH-1] = 3;

    printf("After:\n\n");
    for(int i = 0; i < (SIZE + 1); i++)
    {
        printf("feld_ptr[%d] = %d\n", i, feld_ptr[i]);
    }

    free(feld_ptr);

    return 0;
}

Вывод:

Before:

feld_ptr[0] = 0
feld_ptr[1] = 1
feld_ptr[2] = 2
feld_ptr[3] = 4
feld_ptr[4] = 5
feld_ptr[5] = 6
feld_ptr[6] = 7
feld_ptr[7] = 8
feld_ptr[8] = 9

After:

feld_ptr[0] = 0
feld_ptr[1] = 1
feld_ptr[2] = 2
feld_ptr[3] = 3
feld_ptr[4] = 4
feld_ptr[5] = 5
feld_ptr[6] = 6
feld_ptr[7] = 7
feld_ptr[8] = 8
feld_ptr[9] = 9
0 голосов
/ 06 мая 2020

Как указано выше, вы не можете увеличить размер массива. В этом случае я предлагаю два решения:

  1. Использование указателя в функции вставки. В этом случае вы должны выделить для этого указателя с помощью size = length of old array + 1. Функция вставки становится такой:
int * insertArray(int* arr, int length, int value, int pos) 
{
    int * array = malloc(sizeof(int) * (length + 1));
    if(!array) {
       return NULL;
    }
    for(int i = 0; i < length; i++) {
        array[i] = arr[i];
    }
    int i;

    if (pos < length)
    {
        for (i = length; i > pos; i--)
        {
            array[i] = array[i - 1];
        }
        array[i] = value;
        length++;
    }

    else if (pos == length)
    {
        array[pos] = value;
        length++;
    }
    return array;
}

Затем в основной функции:

int main()
{
    int feld[9] = {0,1,2,4,5,6,7,8,9};

    size_t length = sizeof(feld) / sizeof(int);

    int * array = insertArray(feld, length, 3, 3);

    for (int i = 0; i <= length; i++)
    {
        printf("%d,", array[i]);
    }
    free(array);
    return 0;
}
Использование указателя в основной функции вместо массива, затем перераспределение указателя в функции вставки.
void insertArray(int* array, int length, int value, int pos) 
{
    array = realloc(array, sizeof(int) * (length + 1));
    if (!array)
       return;
    ...
}

В основной функции:

int main()
{
    int *feld = malloc(sizeof(int) * 9);
    if(!feld)
      return -1;

    for(int i = 0; i < 9; i++) {
        if(i<3)
          feld[i] = i;
        else
          feld[i] = i+1;
    }

    insertArray(feld, 9, 3, 3);

    for (int i = 0; i <= 9; i++)
    {
        printf("%d,", feld[i]);
    }
    free(feld);
    return 0;
}

0 голосов
/ 06 мая 2020

Вам нужно использовать кучу вместо стека для вашей задачи.

Как сказано в комментариях под вашим сообщением, если вы объявите массив, он будет иметь фиксированный размер. Конечно, вы можете отредактировать его и добавить другое значение, но помните, что вы выделяете дополнительное пространство в памяти, которое не соответствует вашему массиву, тем самым уничтожая некоторые другие переменные в стеке (возможно), что небезопасно.

Вы можете использовать malloc(), чтобы зарезервировать необходимый объем памяти в куче, а затем функцию realloc(), чтобы изменить начальный размер. Не забудьте free() в памяти в конце вашей программы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...