Можно ли определить размер массива во времени выполнения в C

В новинку для C, большое спасибо за справку.

Действительно ли возможно определить массив в C или без определения его размера или без инициализации его.

Например, я могу предложить пользователю вводить номера и хранить их в международном массиве? Я не буду знать, сколько номеров они введут заранее.

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

6
задан tkrishtop 27 August 2019 в 13:19
поделиться

8 ответов

Arrays, by definition, are fixed-size memory structures. You want a vector. Since Standard C doesn't define vectors, you could try looking for a library, or hand-rolling your own.

You need to do dynamic allocation: You want a pointer to a memory address of yet-unkown size. Read up on malloc and realloc.

3
ответ дан 8 December 2019 в 04:09
поделиться

Well, you can dynamically allocate the size:

#include <stdio.h>

int main(int argc, char *argv[])
{
  int *array;
  int cnt;
  int i;

  /* In the real world, you should do a lot more error checking than this */
  printf("enter the amount\n");
  scanf("%d", &cnt);

  array = malloc(cnt * sizeof(int));

  /* do stuff with it */
  for(i=0; i < cnt; i++)
    array[i] = 10*i;

  for(i=0; i < cnt; i++)
    printf("array[%d] = %d\n", i, array[i]);

  free(array);

  return 0;
}
13
ответ дан 8 December 2019 в 04:09
поделиться

Если все, что вам нужно, это структура данных, в которой вы можете динамически изменять ее размер, то лучшим вариантом, который вы можете выбрать, является связанный список. Вы можете добавлять данные в список, динамически выделяя для них память, и это будет намного проще !!

2
ответ дан 8 December 2019 в 04:09
поделиться

Возможно, что-то вроде этого:

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

/* An arbitrary starting size. 
   Should be close to what you expect to use, but not really that important */
#define INIT_ARRAY_SIZE 8

int array_size = INIT_ARRAY_SIZE;
int array_index = 0;
array = malloc(array_size * sizeof(int));

void array_push(int value) {
  array[array_index] = value;
  array_index++;
  if(array_index >= array_size) {
    array_size *= 2;
    array = realloc(array, array_size * sizeof(int));
  }
}

int main(int argc, char *argv[]) {
  int shouldBreak = 0;
  int val;
  while (!shouldBreak) {
    scanf("%d", &val);
    shouldBreak = (val == 0);
    array_push(val);
  }
}

Это запросит числа и сохранит их в массиве, как вы просили. Он завершится, когда будет передано значение 0.

Вы создаете функцию доступа array_push для добавления в свой массив, вы вызываете realloc из этой функции, когда у вас заканчивается место. Вы каждый раз удваиваете количество выделенного пространства. В лучшем случае вы выделите вдвое больше памяти, чем вам нужно, в худшем случае вы вызовете realloc log n раз, где n - конечный предполагаемый размер массива.

Вы также можете проверить наличие сбоя после вызова malloc и realloc. Я не делал этого выше.

6
ответ дан 8 December 2019 в 04:09
поделиться

Вы можете использовать malloc для динамического распределения памяти (т.е. размер неизвестен до времени выполнения).

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

UPDATE

Просто прочтите ваш комментарий к другому ответу.

Вы запрашиваете массив с динамически изменяющимся размером.

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

См. этот вопрос: Есть ли реализация массива / динамического массива с автоматическим изменением размера для C, которая поставляется с glibc?

0
ответ дан 8 December 2019 в 04:09
поделиться

Для чего-то вроде этого вы можете захотеть изучить такие структуры данных, как: Связанные списки (идеально подходят для этой ситуации) Различные деревья (двоичные деревья, кучи и т. Д.) Стеки и очереди

Но что касается создания экземпляра массива переменного размера, это на самом деле невозможно.

Наиболее близким к динамическому массиву является использование malloc и связанных с ним команд (delete, realloc и т. Д.).

Но в этой ситуации использование таких команд, как malloc, может привести к необходимости расширения массива - дорогостоящей операции, когда вы инициализируете другой массив, а затем копируете в него старый массив. Списки и другие типы данных обычно лучше меняют размер.

0
ответ дан 8 December 2019 в 04:09
поделиться

Если вы ищете возможности массивов и не хотите менять свои собственные, попробуйте следующее:

  1. Glib
  2. Apache APR
  3. NSPR
0
ответ дан 8 December 2019 в 04:09
поделиться

Если вы новичок, возможно, вы пока не хотите иметь дело с malloc и free . Поэтому, если вы используете GCC, вы можете размещать в стеке массивы переменного размера, просто указав размер в виде выражения.

Например:

#include <stdio.h>
void dyn_array(const unsigned int n) {
        int array[n];
        int i;

        for(i=0; i<n;i++) {
                array[i]=i*i;
        }
        for(i=0; i<n;i++) {
                printf("%d\n",array[i]);
        }
}
int main(int argc, char **argv) {
        dyn_array(argc);
        return 0;
}

Но имейте в виду, что это нестандартное расширение, поэтому вам не следует не рассчитывайте на это, если портативность имеет значение.

0
ответ дан 8 December 2019 в 04:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: