Заполнить элементы многомерного массива нулями
У меня есть 2d, и я хочу установить элементы на ноль без зацикливания всех элементов
int a[100][200];
Я не могу инициализировать их в момент объявления.
11 ответов
Пытаться
int a[100][200] = {{0}};
Если вы инициализируете некоторые (но не все) элементы, остальные будут инициализированы нулем. Здесь вы только явно инициализируете первый элемент первого подмассива, а остальное заботится компилятор.
Пытаться memset(a,0,sizeof(a));
Это просто перезаписывает память, используемую массивом, с 0 байтами. Не делайте этого для пользовательских типов данных, если вы действительно не знаете, что делаете. Есть также std::fill
а также std::fill_n
, что больше C++ иш (но не самый простой способ здесь).
Для C++ вы можете использовать метод std:fill из заголовка алгоритма.
int a[x][y];
std::fill(a[0], a[0] + x * y, 0);
Итак, в вашем случае вы можете использовать это:
int a[100][200];
std::fill(a[0], a[0] + 100 * 200, 0);
Конечно, 0 можно изменить для любого значения int.
C++ позволяет многомерным массивам полностью итерироваться указателем базового элемента. Так что вы можете использовать std::fill
и передать его самый первый элемент nonarray
std::fill(a[0] + 0, a[99] + 100, 0);
В C это формально не разрешено, и вам нужно было бы выполнять итерацию по каждому подмассиву отдельно, потому что итерация за указателем конца конца первого подмассива вызывает неопределенное поведение в C. Тем не менее, на практике это все еще работает.
Во многих ответах использовалась указательная арифметика с fill
, Это можно сделать проще:
int a[N][K];
fill(a[0], a[N], 0);
В принципе, a[N]
является первым адресом памяти после многомерного массива, независимо от количества измерений. Это тоже работает:
int a[N][K][L][M];
fill(**a[0], **a[N], 0);
Звездочки здесь разыменовывают указатели до int*
тип (массив скобок разыменования int****
в int***
, две звездочки делают остальную работу).
Что именно означает "я не могу инициализировать их в точке объявления"? "Не знаю как"? Или "не могу изменить код там"?
Язык C++ имеет функцию, которая инициализирует весь массив до 0 в точке объявления
int a[100][100] = {};
(примечание, нет явного 0
действительно необходимо между {}
). Вы можете использовать это или нет?
Если вы не можете, то ваши варианты: используйте memset
-hack, 1D-reinterpretation-hack или установить каждый элемент явно, перебирая массив (ы) (с помощью или без помощи fo std::fill
).
Если этот массив объявлен в области видимости файла или в области функций, но со статическим значением, он автоматически обнуляется для вас, вам не нужно ничего делать. Это хорошо только для одной инициализации при запуске программы; если вам нужно сбросить его, вы должны написать это самостоятельно. я хотел бы использовать memset
для этого.
Если он объявлен в области видимости функции без статического, вам нужно использовать memset
или явный инициализатор - одиночный = { 0 }
достаточно, вам не нужно выписывать все 2002 нуля, как кто-то другой предложил.
Я проверил это решение, и оно сработало.
int arr[100][200];
for (int i=0; i<100; i++)
for (int j=0; j<200; j++) (arr[i][j] = 0);
for (int i=0; i<100; i++)
for (int j=0; j<200; j++) cout << (arr[i][j]);
Использование
int a[100][200]={0};
Это инициализирует все элементы массива с 0
memset
упомянутый подход (memset(a,0,sizeof(a));
) будет работать, но как насчет того, чтобы сделать это способом C++ (по вашему тегу) и с использованием вектора?
std::vector<std::vector<int> > a;
a.assign(100, std::vector<int>(200));
Поскольку размер четко определен, все, что вам нужно, это завершающие скобки...
int a[100][200]();