Почему моя функция изменяет значение аргумента ввода? - PullRequest
0 голосов
/ 21 сентября 2018

Массивы переменной длины не допускаются.Но потом я недавно узнал, что пользовательская функция манипулирует исходным массивом, а не собственной копией.Поэтому я подумал о создании функции, которая получает желаемый размер массива пользователем и, следовательно, об изменении размера (я также инициализировал массив в этой функции).

void fill_array(int array[], int size, int in_val);

void main(){
    int n, value, list[1], ctr;
    clrscr();

    printf("Enter the size of the array: ");
    scanf("%d", &n);
    printf("Enter the value that you want all of the elements to take initially: ");
    scanf("%d", &value);
    printf("\nAfter scanning value, n = %d\n", n);

    fill_array(list, n, value);

    printf("\nAfter Function fill_array Execution");
    printf("\nThe values of each element of the array is now: %d ", list[0]);
    printf("%d ", list [1]);
    printf("%d ", list [2]);
    printf("\nn = %d\n", n);
    printf("value = %d\n", value);

    getch();
}

void fill_array(int array[], int size, int in_val){
    int ctr;

    for (ctr = 0; ctr < size; ++ctr)
        array[ctr] = in_val;
    printf("\nInside Function");
    printf("\nn = %d\n", size);
    printf("value = %d\n", in_val);
}

Вот консоль / пример прогона:

Enter the size of the array: 3

Enter the value that you want all of the elements to take initially: 444

After scanning value, n = 3

Inside Function

n = 3

value = 444

После функции fill_array Выполнение

Значение каждого элемента массива теперь равно: 444444 444

n = 444

значение = 444

Функция изменила list.Однако, как вы можете видеть, оно также изменило значение n.После каждого выполнения fill_array, n всегда равняется value.Кто-нибудь, пожалуйста, объясните мне, почему функция меняет значение n.Я не хочу, чтобы значение n изменилось.

Ответы [ 3 ]

0 голосов
/ 21 сентября 2018

Как только массив определен, изменить его размер невозможно.

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

printf("Enter the size of the array: ");
if (scanf("%d", &n) != 1) exit(1);
printf("Enter the value that you want all of the elements to take initially: ");
if (scanf("%d", &value) != 1) exit(1);

int * list = malloc(n * sizeof *list); // allocate memory

fill_array(list, n, value);

// and just use it as an array
list[1] = list[0] + 42;         // assuming n >= 2
...
...

free(list);

Если вам позже потребуется изменить размер массива, вы можете использовать функцию realloc

0 голосов
/ 21 сентября 2018

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

Тогда вы не передадите как n размермассив, но количество элементов.

Таким образом, вы просто зацикливаетесь на массиве и останавливаетесь на длине n.Вам нужно переписать функцию fill_array, чтобы выполнить это поведение.

Почему вы получаете вывод из-за undefined behaviour.См. Ответ PW для получения дополнительной информации об этом.

0 голосов
/ 21 сентября 2018

Внутри функции fill_array вы пытаетесь записать в память, выходящую за пределы массива list.Это приведет к неопределенному поведению.

Из вики-статьи о неопределенное поведение :

Поведение некоторых языков программирования, в частности C и C ++, в некоторых случаях не определено.В стандартах для этих языков семантика определенных операций описана как неопределенная.Эти случаи обычно представляют однозначные ошибки в коде, например, , например, индексирование массива за его пределами .

В проекте комитета C (N1570) говорится о неопределенном поведении:

3.4.3
1 неопределенное поведение
поведение при использовании непереносимой или ошибочной программной конструкции или ошибочных данных, для которых настоящий международный стандарт не предъявляет никаких требований
2 ПРИМЕЧАНИЕ Возможное неопределенное поведение колеблется от полного игнорирования ситуации с непредсказуемыми результатами до поведения во время перевода или выполнения программы документированным образом, характерным для среды (с выдачей диагностического сообщения или без него),прекратить перевод или выполнение (с выдачей диагностического сообщения).

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