Динамическая длина массива в C [дубликат]

5
задан David 25 October 2009 в 11:17
поделиться

10 ответов

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

  1. Glib
  2. Apache APR
  3. NSPR
0
ответ дан blwy10 24 August 2018 в 02:59
поделиться

Ну, вы можете динамически выделить размер:

#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;
}
11
ответ дан BobbyShaftoe 24 August 2018 в 02:59
поделиться
  • 1
    Конечно, вам нужно знать множество чисел, которые вы добавляете при каждом запуске. realloc в противном случае. – Tordek 20 October 2009 в 02:26
  • 2
    Спасибо за опечатку Dana. – BobbyShaftoe 20 October 2009 в 02:31
  • 3
    Спасибо за помощь. Наверное, я не задал вопрос четко в своем первом посте. Проблема в том, что мы не знаем, сколько номеров вводит пользователь, и пользователь тоже не знает. Скажем, мы просим пользователя ввести любое количество чисел, и мы рассчитаем для него среднее значение. Все, что ему нужно сделать, это ввести номер, нажать enter, ввести другой номер ... и ввести Q, когда он будет завершен. Как сохранить эти числа в массиве, не спрашивая у пользователя, сколько цифр он планирует ввести? Это будет простое использование векторов в C ++ ... – user 20 October 2009 в 02:38
  • 4
    извините, средний показатель является плохим, так как все, что нам нужно, это сумма, скажем, нам нужно держать все числа, чтобы сделать какой-то причудливый расчет ... – user 20 October 2009 в 02:48
  • 5
    @Bobby - Говоря о опечатках, "динамически" не имеет "o" в этом. Но это не серьезная проблема. – Chris Lutz 20 October 2009 в 03:29

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

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

UPDATE

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

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

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

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

0
ответ дан Community 24 August 2018 в 02:59
поделиться

Если вы новичок, возможно, вы еще не хотите иметь дело с 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
ответ дан fortran 24 August 2018 в 02:59
поделиться
  • 1
    Это не «нестандартное выражение», - к моменту написания ответа, это был международный стандарт на 10 лет. Проблема заключается в многих действительно нестандартных компиляторах от таких некомпетентных компаний, таких как Microsoft, которые даже не поддерживают 10-летние стандарты. – Antti Haapala 16 January 2018 в 13:54

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

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

Ближайшим к динамическому массиву является использование malloc и связанных с ним команд (delete, realloc, и т.д).

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

0
ответ дан Matthew 24 August 2018 в 02:59
поделиться

Вышеуказанные ответы верны, но есть одна коррекция, функция malloc () резервирует блок памяти указанного размера и возвращает указатель типа void *, который может быть введен в указатель любой формы. Синтаксис: ptr = (cast-type *) malloc (размер байта)

#include<stdio.h>
#include<cstdlib>
int main(int argc,char* argv[]){
int *arraySize,length;
scanf("%d",&length);
arraySize = (int*)malloc(length*sizeof(int));
for(int i=0;i<length;i++)
    arraySize[i] = i*2;
for(int i=0;i<length;i++)
    printf("arrayAt[%d]=%d\n",i,arraySize[i]);
free(arraySize);
}
0
ответ дан Nagendra 24 August 2018 в 02:59
поделиться

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

2
ответ дан Peter Mortensen 24 August 2018 в 02:59
поделиться
  • 1
    +1, простой связанный список звучит как лучший вариант, учитывая информацию в вопросе. Если бы OP мог прояснить, что он собирается делать с информацией после ее чтения, мы сможем предложить еще более подходящую структуру данных. – Graphics Noob 21 October 2009 в 06:05

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

#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
ответ дан Phil Miller 24 August 2018 в 02:59
поделиться
  • 1
    В другом комментарии вы упомянули, что хотите, чтобы программа перестала запрашивать номера, когда пользователь поставляет «q». Сделайте это, вызвав scanf с% s вместо% d. Затем вы сравниваете символ с «q» и решаете, выйти или нет. Затем вам нужно преобразовать его в int, вызвав atoi – Joel 20 October 2009 в 03:03
  • 2
    Большое спасибо, это умно и показало мне другое отношение к этой проблеме: не обязательно быть точным, приблизительным, а затем расширять позже. Я, вероятно, посмотрю, как вектор реализован на C ++, что, я думаю, предложит некоторые идеи в этой проблеме. – user 20 October 2009 в 03:11

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

Вам нужно выполнить динамическое распределение: вы хотите, чтобы указатель на адрес памяти еще неранного размер. Читайте на malloc и realloc.

3
ответ дан Tordek 24 August 2018 в 02:59
поделиться
  • 1
    Кроме того, просто чтобы добавить к этому, один популярный метод для выполнения realloc () заключается в том, что всякий раз, когда вам нужно перераспределить (потому что вы выбежали из комнаты), удвойте размер массива; таким образом вы делаете как можно меньше вызовов realloc. – BobbyShaftoe 20 October 2009 в 02:27
  • 2
    Удвоение размера при каждом перераспределении не связано с минимальным количеством вызовов realloc, а с сохранением хорошей асимптотической эффективности. Если вы добавляете постоянный приращение к вектору при каждом перераспределении, то нажатие на n элементов занимает O(n^2). Если вы умножаете размер на некоторый коэффициент & gt; 1 каждый при перераспределении, каждый толчок принимает амортизированное постоянное время, и весь процесс занимает O(n) раз. – Phil Miller 20 October 2009 в 03:18

Да, абсолютно. C99 представил VLA или переменную длину массива. Некоторый простой код будет таким:

#include <stdio.h>

int main (void) {

    int arraysize;
    printf("How bid do you want your array to be?\n");
    scanf("%d",&arraysize);
    int ar[arraysize];  
    return 0;
}
1
ответ дан wildplasser 24 August 2018 в 02:59
поделиться
  • 1
    Блок кода: = отступ с четырьмя пробелами. Ярлык: выделить блок и нажать CTRL-k. НТН. – wildplasser 15 February 2012 в 22:27
Другие вопросы по тегам:

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