Похоже на странный вопрос, но когда я программирую в c++ или c, например, мне приходится жестко кодировать размер массива.
Невозможно ли пользователю через терминал ввести размер. Да, я не могу понять, возможно ли это и интересно, почему это запрещено.
РЕДАКТИРОВАТЬ:
До сих пор я понимаю, что массивы являются статическими, и мы можем использовать списки ссылок, поскольку они более динамичны. Почему переменные массивы являются динамическими?
Когда вы выделяете блок памяти, вы делаете именно это - блок памяти, размер которого вы запрашиваете, выделяется, и вам предоставляется указатель на него.
Если вы попытаетесь выйти за пределы этого блока, вы читаете/записываете в память, которая не принадлежит массиву.
Для расширения массива вам потребуется больше памяти, но для этого блока недостаточно. Вам нужно выделить новый блок и изменить указатель на этот новый блок, вы не сможете сделать это, изменив размер существующего как пространство после того, как ваш блок уже может быть использован чем-то другим!
Вот почему невозможно изменить размер существующего массива.
std::vector
- динамический массив. Используйте это.
Массивы переменной длины действительно существуют в C и как расширение языка GCC для C++, а в следующем C++ 14 - его внешний вид.
В этом ответе я предположил, что вы имеете в виду массивы, которые могут иметь границы времени выполнения, даже если эти границы не могут быть впоследствии изменены.Это соответствует содержимому вашего вопроса, но не его название.К счастью, std::vector
обеспечивает оба.
Я также предположил C++, потому что кого мы шутим?
Это конструктивное решение C, что встроенные массивы - это простая и быстрая структура, которая отражает операции, которые может быть дешево достигнута процессором. В языках с массивами с переменным размером акт изменения размера массива может быть очень дорогостоящим, так как под кодом будет вызываться перераспределение нового блока памяти другого размера и копирование существующего содержимого.
В C вы сами контролируете эти операции изменения размера, используя кучу и malloc/realloc, потому что это тип языка C. C++ имеет массивы, которые делают это для вас, как std :: vector, или даже в C вы можете использовать библиотечные функции для управления динамическими массивами. Просто простой массив C спроектирован так, чтобы быть простым и быстрым.
В C99 и более новых стандартах вы можете использовать VLA:
int len = ask_length_from_user();
int array[len];
for (int i = 0; i < len ; ++i) array[i] = i;
Обратите внимание, что с VLA вы должны быть осторожны относительно размера, потому что VLA будет храниться в стеке, что часто довольно ограничено (только мегабайты, а не гигабайты максимальной кучи).
Возможно, лучше использовать кучу:
int len = ask_length_from_user();
int *array = malloc (sizeof(int) * len);
if (!array) exit(1); // malloc failed
for (int i = 0; i < len ; ++i) array[i] = i;
Обратите внимание, как вы можете получить доступ к выделенной памяти с тем же синтаксисом, что и при доступе к массиву. Кроме того, вы можете изменить размер памяти, выделенной с помощью malloc
:
int tmplen = ask_length_from_user();
int *tmparr = realloc(array, sizeof(int) * tmplen);
if (tmparr) {
array = tmparr;
// note: following loop doesn't do anything if len >= newlen
while(len < tmplen) array[len++] = len;
}
// else realloc failed, keep original array and len
Наконец, с памятью malloc
, помните!
free(array);
Вы должны использовать, например, std :: vector:
int len = ask_length_from_user();
std::vector<int> array;
for (int i = 0; i < len ; ++i) array.push_back(i);
// alternatively, you can resize the array and use indexes like in C snippets:
array.resize(len);
for (int i = 0; i < len ; ++i) array[i] = i;
И код для изменения размера, просто с push_back
:
int tmplen = ask_length_from_user();
if (tmplen < len) {
len = tmplen;
array.resize(tmplen);
} else {
while (len < tmplen) array.push_back(len++);
}
Как вы можете видеть, коды C и C++ совершенно разные. Это разные языки, и редко бывает разумно задавать одно и то же. C-код (кроме VLA в текущем стандарте C++) будет работать в C++, но делать это не очень хорошо, это нехорошо C++, и по крайней мере вам следует избегать malloc
и использовать new
(хотя он не поддержка изменения размеров красиво).
std::vector<int> array(len);
или array.resize(len);
[перед циклом]
push_back
Поскольку статические (автоматические) переменные выделяются в стеке, а адрес стека-фрейма фиксируется во время жизни функции, поэтому адрес переменной также является статическим. Как только вы объявляете массив в некоторой позиции, вы не можете сделать его более крупным, не перекрывая другие переменные после. C99 допускает массивы переменной длины, размеры которых известны только во время выполнения, но их размеры по-прежнему фиксированы, вы не можете изменять размер после объявления.
Но для изменения размера массива вам не нужно C99 или vector. Вы всегда можете выделить динамическую память в куче и использовать указатель как массив, потому что они не "разные" при использовании этого способа. Динамическая память изменяется при распределении новой области памяти и при необходимости копирует данные в новое место.