Переопределение размера массива - PullRequest
0 голосов
/ 29 января 2019

Так что в основном в соответствии с определением массива мы не можем изменить размер массива.Но если я добавляю элемент в тот же массив, смещая другие элементы вправо от массива, размер массива будет увеличиваться.

Как это возможно?

#include<stdio.h>

int main() {
  int n, j, k, item;
  printf("Enter size of array:\n");
  scanf("%d", &n);
  printf("Enter element to insert and position of element:\n");
  scanf("%d,%d", &item, &k);
  int a[n];
  for (j = 0; j < n; j++) {
    printf("Enter a[%d] element:\n", j);
    scanf("%d", &a[j]);
  }
  j = n - 1;
  while (j >= k - 1) {
    a[j + 1] = a[j];
    j = j - 1;
  }
  a[k - 1] = item;
  for (j = 0; j <= n; j++) {
    printf("%d\n", a[j]);

  }
}

Ответы [ 4 ]

0 голосов
/ 29 января 2019

.... массив мы не можем изменить .. Но если я (сделаю что-то особенное) ... размер массива увеличится.

Как это возможно?

Неопределенное поведение

Массивы не могут изменить размер после определения.

Код пытается присвоить a[j + 1] с помощью j = n-1, то есть a[n].Это внешний массив a[] и, таким образом, неопределенное поведение .Остальная часть кода не имеет значения, поскольку в этот момент все возможно, сбой кода, сообщение об ошибке, даже очевидное успешное расширение массива и т. Д.

  int a[n];
  ...
  j = n - 1;
  while (j >= k - 1) {
    a[j + 1] = a[j]; // To attempt access to `a[n]` is UB
0 голосов
/ 29 января 2019

Сдвиг содержимого массива вправо не изменит размер массива.Если массив уже не был достаточно большим, чтобы содержать результат сдвига, значит, вы запустили объект массива и вызвали неопределенное поведение.

Невозможно динамически увеличить размер переменной со статическимили автоматическая длительность (например, глобальные или локальные переменные), и это включает в себя массивы.Если ваш компилятор поддерживает массивы переменной длины (VLA), изменение значения выражения, контролирующего размерность массива, не влияет на размер массива.

int main (void) {
    int n = 3;
    int v[n];
    printf("%zu\n", sizeof(v));
    ++n;
    printf("%zu\n", sizeof(v));
}

Приведенная выше программа напечатает одно и то же значение дважды.

0 голосов
/ 29 января 2019

Если вы объявите массив как

T a[N]; // assume N is a constant expression

, тогда a может содержать только N элементов типа T - не больше, не меньше.Вы не можете добавлять дополнительные элементы в массив и не можете удалять элементы из массива.

Однако ...

C не вызывает проверку границ при подписке массива, поэтому возможно, что вы можете читать или писать после конца массива, например

a[N + 2] = x;

Поведение при этом: undefined - ваша программа может работать должным образом, или она может сразу аварийно завершиться, или вы можете повредить другие объекты в программе.Среда выполнения (скорее всего) не будет генерировать исключение типа IndexOutOfBounds.

Существует вещь, называемая массивом переменной длины , который был добавлен в C99, где размер массива не является константным выражением:

size_t size = some_value();
T a[size];

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

Если вы динамически выделяете кусок памяти, используя

T *a = malloc( sizeof *a * some_size );

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

T *tmp = realloc( a, sizeof *a * (some_size * 2) ); 
if ( tmp )
{
  a = tmp;
  some_size *= 2;
}
0 голосов
/ 29 января 2019

Я не совсем уверен, что вы спрашиваете, но для любых читателей, заинтересованных в знании, как динамически изменять размер массива в C: если массив объявлен в стековой памяти, его размер не может измениться.Однако блок памяти, предназначенный для использования в качестве массива, объявляется в куче (т. Е. С malloc или calloc), при необходимости может быть realloc с другим размером:

int *data = malloc(10 * sizeof(int)), *data2 = NULL;
int i;
if(data == NULL)
{
     perror("malloc");
     exit(EXIT_FAILURE);
}
for (i = 0; i < 10; i++)
{
    data[i] = i;
}

data2 = realloc(data, 11 * sizeof(int));
if(data2 == NULL)
{
     free(data);
     perror("realloc");
     exit(EXIT_FAILURE);
}
else 
{ 
    data = data2; 
}
data[10] = 10;

for (i = 0; i < 11; i++)
    printf("%d ", data[i]);

free(data);
data = NULL;

Смещение элементов в массиве на один элемент не изменит его размера.

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