Инициализация всех элементов массива одним значением по умолчанию в C ++?

Примечания C ++: инициализация массива имеет хороший список по инициализации массивов . у меня есть

int array[100] = {-1};

ожидая, что он будет заполнен -1, но это не так, только первое значение, а остальные - 0, смешанные со случайными значениями.

Код

int array[100] = {0};

работает нормально и устанавливает для каждого элемента значение 0.

Что мне здесь не хватает ... Нельзя инициализировать его, если значение не равно нулю?

И 2: инициализация по умолчанию (как указано выше) быстрее, чем обычный цикл по всему массиву и присваивает значение, или она делает то же самое?


person Milan    schedule 30.06.2009    source источник
comment
Поведение в C и C ++ отличается. В C {0} - это особый случай для инициализатора структуры, однако AFAIK не для массивов. int array [100] = {0} должен быть таким же, как array [100] = {[0] = 0}, что в качестве побочного эффекта обнулит все остальные элементы. Компилятор C НЕ должен вести себя так, как вы описали выше, вместо этого int array [100] = {- 1} должен установить для первого элемента значение -1, а для остальных - 0 (без шума). В C, если у вас есть struct x array [100], использование = {0} в качестве инициализатора НЕ допустимо. Вы можете использовать {{0}}, который инициализирует первый элемент и обнуляет все остальные, в большинстве случаев это будет одно и то же.   -  person Fredrik Widlund    schedule 26.02.2015
comment
@FredrikWidlund Это то же самое на обоих языках. {0} не является особым случаем для структур или массивов. Правило состоит в том, что элементы без инициализатора инициализируются, как если бы они имели 0 в качестве инициализатора. Если есть вложенные агрегаты (например, struct x array[100]), то инициализаторы применяются к неагрегатам в строковом порядке; при этом фигурные скобки можно опустить. struct x array[100] = { 0 } действительно в C; и действителен в C ++ до тех пор, пока первый член struct X принимает 0 в качестве инициализатора.   -  person M.M    schedule 03.12.2015
comment
{ 0 } не является особенным в C, но гораздо сложнее определить тип данных, который нельзя инициализировать с его помощью, поскольку нет конструкторов и, следовательно, нет способа остановить 0 от неявного преобразования и присвоения something .   -  person Leushenko    schedule 03.04.2016
comment
Проголосовали за повторное открытие, потому что другой вопрос касается C. Существует множество способов инициализации массива в C ++, которые недопустимы в C.   -  person xskxzr    schedule 15.06.2018
comment
Также проголосовали за повторное открытие - C и C ++ - разные языки   -  person Pete    schedule 21.06.2019
comment
Я удалил тег C, поскольку этот вопрос явно ориентирован на C ++, и соответствующим образом отредактировал заголовок вопроса. Теперь вопрос можно открыть повторно, потому что он больше не является дубликатом проиллюстрированного вопроса C. Для всех тех из вас, кто столкнется с этим вопросом в будущем и может захотеть взглянуть на тот же вопрос для C, вот ссылка: Как инициализировать все элементы массива одинаковым значением?   -  person RobertS supports Monica Cellio    schedule 26.02.2020


Ответы (13)


Используя синтаксис, который вы использовали,

int array[100] = {-1};

говорит: «Установите первый элемент в -1, а остальные в 0», поскольку все пропущенные элементы установлены в 0.

В C ++, чтобы установить для всех их значение -1, вы можете использовать что-то вроде std::fill_n ( с <algorithm>):

std::fill_n(array, 100, -1);

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

person Evan Teran    schedule 30.06.2009
comment
Это также ответило на косвенный вопрос о том, как легко заполнить массив значениями по умолчанию. Спасибо. - person Milan; 01.07.2009
comment
Применимо ли это правило для первого элемента к -1, а для остальных - к 0? - person Matt Joiner; 12.01.2012
comment
@MattJoiner: да, я так считаю. - person Evan Teran; 12.01.2012
comment
Обратите внимание, что вам нужно будет добавить #include <vector>, чтобы использовать это решение. - person chessofnerd; 23.05.2013
comment
@chessofnerd: неточно, #include <algorithm> - правильный заголовок, <vector> может включать или не включать его косвенно, это будет зависеть от вашей реализации. - person Evan Teran; 23.05.2013
comment
Вам не нужно прибегать к инициализации массива во время выполнения. Если вам действительно нужно, чтобы инициализация происходила статически, можно использовать вариативные шаблоны и вариативные последовательности, чтобы сгенерировать желаемую последовательность ints и развернуть ее в инициализатор массива. - person void-pointer; 03.06.2013
comment
Я бы предпочел int array[100] = {-1, };, иначе это может сбить с толку того, что вы пытаетесь инициализировать все элементы до -1. - person Deqing; 08.08.2013
comment
@Evan Teran Я думаю, что правильный синтаксис для использования fill_n для 2D-массива - int array2D[3][2]; std::fill_n(&array2D[0][0], 6, -1);. Однако VS2012 выдает предупреждение 'std :: _ Fill_n': вызов функции с параметрами, которые могут быть небезопасными - этот вызов полагается на вызывающего, чтобы проверить правильность переданных значений. Чтобы отключить это предупреждение, используйте -D_SCL_SECURE_NO_WARNINGS. См. Документацию по использованию проверенных итераторов Visual C ++. - person ontherocks; 03.10.2013
comment
@ontherocks, нет правильного способа использовать один вызов fill_n для заполнения всего 2D-массива. Вам нужно перебрать одно измерение, заполняя другое. - person Evan Teran; 03.10.2013
comment
Это ответ на другой вопрос. std::fill_n не инициализация. - person Ben Voigt; 01.07.2014

Существует расширение компилятора gcc, которое позволяет использовать синтаксис:

int array[100] = { [0 ... 99] = -1 };

Это установит для всех элементов значение -1.

Это известно как «Назначенные инициализаторы», дополнительную информацию см. здесь.

Обратите внимание, что это не реализовано для компилятора gcc c ++.

person Callum    schedule 30.06.2009
comment
Потрясающие. Этот синтаксис, похоже, также работает в clang (поэтому может использоваться в iOS / Mac OS X). - person JosephH; 07.01.2014

Страница, на которую вы ссылаетесь, уже дала ответ на первую часть:

Если указан явный размер массива, но указан более короткий список инициализации, неуказанные элементы устанавливаются в ноль.

Нет встроенного способа инициализировать весь массив некоторым ненулевым значением.

Что касается того, что быстрее, применяется обычное правило: «Метод, который дает компилятору наибольшую свободу, вероятно, быстрее».

int array[100] = {0};

просто сообщает компилятору «установить эти 100 целых чисел в ноль», что компилятор может свободно оптимизировать.

for (int i = 0; i < 100; ++i){
  array[i] = 0;
}

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

Наконец, если вы хотите установить для массива ненулевое значение, вам следует (по крайней мере, в C ++) использовать std::fill:

std::fill(array, array+100, 42); // sets every value in the array to 42

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

person jalf    schedule 30.06.2009
comment
Хороший ответ. Обратите внимание, что в C ++ (не в C) вы можете использовать int array [100] = {}; и дать компилятору максимальную свободу :) - person Johannes Schaub - litb; 01.07.2009
comment
согласен, отличный ответ. Но для массива фиксированного размера он использовал бы std :: fill_n :-P. - person Evan Teran; 01.07.2009

В C ++ 11 есть еще один (несовершенный) вариант:

std::array<int, 100> a;
a.fill(-1);
person Timmmm    schedule 11.09.2014

С помощью {} вы назначаете элементы так, как они объявлены; остальное инициализируется 0.

Если нет = {} для инициализации, содержимое не определено.

person 0x6adb015    schedule 30.06.2009

Страница, которую вы связали, указывает

Если указан явный размер массива, но указан более короткий список инициализации, неуказанные элементы устанавливаются в ноль.

Проблема со скоростью: любые различия будут незначительны для массивов такого маленького размера. Если вы работаете с большими массивами, и скорость намного важнее размера, вы можете иметь константный массив значений по умолчанию (инициализированных во время компиляции), а затем memcpy их в изменяемый массив.

person laalto    schedule 30.06.2009
comment
memcpy - не очень хорошая идея, поскольку это было бы сопоставимо с простой установкой значений непосредственно по скорости. - person Evan Teran; 01.07.2009
comment
Я не вижу необходимости в копии и массиве const: почему бы не создать модифицируемый массив в первую очередь с предварительно заполненными значениями? - person Johannes Schaub - litb; 01.07.2009
comment
Спасибо за объяснение скорости и за то, как это сделать, если скорость является проблемой из-за большого размера массива (что в моем случае) - person Milan; 01.07.2009
comment
Список инициализаторов создается во время компиляции и загружается во время выполнения. Не нужно копировать вещи. - person Martin York; 01.07.2009
comment
@litb, @Evan: Например, gcc генерирует динамическую инициализацию (много mov) даже при включенной оптимизации. Для больших массивов и жестких требований к производительности вы хотите выполнить init во время компиляции. memcpy, вероятно, лучше оптимизирован для больших копий, чем для множества простых mov. - person laalto; 01.07.2009
comment
@Martin York: Для константных массивов - да. Не для неконстантных массивов. - person laalto; 01.07.2009
comment
@laalto, если это так, то это ошибка: компилятор, согласно стандарту C ++, должен применять статическую инициализацию к таким POD (int [N]), полностью инициализированным константными выражениями (-1, ...). Я так понимаю, вы имеете в виду int data [] = {1, 2, 3}; . Конечно, я говорю об объектах, имеющих область видимости пространства имен. - person Johannes Schaub - litb; 01.07.2009
comment
(Хотя инициализацию с -1, вероятно, лучше выполнить с помощью memset (..., 0xff), предполагая (int32) -1 == 0xffffffff.) - person laalto; 01.07.2009
comment
@laalto: предполагается комплимент 2, что не гарантируется. - person Evan Teran; 01.07.2009
comment
@litb: Ах, объем не был упомянут. Я имел в виду автоматику области видимости функции, а не статику области видимости пространства имен. - person laalto; 01.07.2009
comment
@laalto, о, тогда в этом есть смысл. В конце концов, ему каждый раз нужна новая копия, на случай, если вы впоследствии изменили массив. Глупо, что я не спрашивал сначала о размахе :) - person Johannes Schaub - litb; 01.07.2009

Используя std::array, мы можем сделать это довольно просто в C ++ 14. Это возможно только на C ++ 11, но немного сложнее.

Наш интерфейс - это размер времени компиляции и значение по умолчанию.

template<typename T>
constexpr auto make_array_n(std::integral_constant<std::size_t, 0>, T &&) {
    return std::array<std::decay_t<T>, 0>{};
}

template<std::size_t size, typename T>
constexpr auto make_array_n(std::integral_constant<std::size_t, size>, T && value) {
    return detail::make_array_n_impl<size>(std::forward<T>(value), std::make_index_sequence<size - 1>{});
}


template<std::size_t size, typename T>
constexpr auto make_array_n(T && value) {
    return make_array_n(std::integral_constant<std::size_t, size>{}, std::forward<T>(value));
}

Третья функция предназначена в основном для удобства, поэтому пользователю не нужно создавать std::integral_constant<std::size_t, size> самостоятельно, поскольку это довольно многословная конструкция. Настоящая работа выполняется одной из первых двух функций.

Первая перегрузка довольно проста: она создает std::array размера 0. Нет необходимости в копировании, мы просто создаем его.

Вторая перегрузка немного сложнее. Он передает значение, полученное в качестве источника, а также создает экземпляр make_index_sequence и просто вызывает некоторую другую функцию реализации. Как выглядит эта функция?

namespace detail {

template<std::size_t size, typename T, std::size_t... indexes>
constexpr auto make_array_n_impl(T && value, std::index_sequence<indexes...>) {
    // Use the comma operator to expand the variadic pack
    // Move the last element in if possible. Order of evaluation is well-defined
    // for aggregate initialization, so there is no risk of copy-after-move
    return std::array<std::decay_t<T>, size>{ (static_cast<void>(indexes), value)..., std::forward<T>(value) };
}

}   // namespace detail

Это создает аргументы первого размера - 1 путем копирования значения, которое мы передали. Здесь мы используем наши индексы пакетов переменных параметров просто как что-то для расширения. В этом пакете есть записи size - 1 (как мы указали при построении make_index_sequence), и они имеют значения 0, 1, 2, 3, ..., size - 2. Однако нас не интересуют значения (поэтому мы приводим его к void, чтобы отключить любые предупреждения компилятора). Расширение пакета параметров расширяет наш код примерно до следующего вида (при условии, что size == 4):

return std::array<std::decay_t<T>, 4>{ (static_cast<void>(0), value), (static_cast<void>(1), value), (static_cast<void>(2), value), std::forward<T>(value) };

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

Последний аргумент, который мы называем std::forward, - это небольшая оптимизация. Если кто-то передает временный std :: string и говорит «сделайте массив из 5 таких», мы хотели бы иметь 4 копии и 1 перемещение вместо 5 копий. std::forward гарантирует, что мы это сделаем.

Полный код, включая заголовки и некоторые модульные тесты:

#include <array>
#include <type_traits>
#include <utility>

namespace detail {

template<std::size_t size, typename T, std::size_t... indexes>
constexpr auto make_array_n_impl(T && value, std::index_sequence<indexes...>) {
    // Use the comma operator to expand the variadic pack
    // Move the last element in if possible. Order of evaluation is well-defined
    // for aggregate initialization, so there is no risk of copy-after-move
    return std::array<std::decay_t<T>, size>{ (static_cast<void>(indexes), value)..., std::forward<T>(value) };
}

}   // namespace detail

template<typename T>
constexpr auto make_array_n(std::integral_constant<std::size_t, 0>, T &&) {
    return std::array<std::decay_t<T>, 0>{};
}

template<std::size_t size, typename T>
constexpr auto make_array_n(std::integral_constant<std::size_t, size>, T && value) {
    return detail::make_array_n_impl<size>(std::forward<T>(value), std::make_index_sequence<size - 1>{});
}

template<std::size_t size, typename T>
constexpr auto make_array_n(T && value) {
    return make_array_n(std::integral_constant<std::size_t, size>{}, std::forward<T>(value));
}



struct non_copyable {
    constexpr non_copyable() = default;
    constexpr non_copyable(non_copyable const &) = delete;
    constexpr non_copyable(non_copyable &&) = default;
};

int main() {
    constexpr auto array_n = make_array_n<6>(5);
    static_assert(std::is_same<std::decay_t<decltype(array_n)>::value_type, int>::value, "Incorrect type from make_array_n.");
    static_assert(array_n.size() == 6, "Incorrect size from make_array_n.");
    static_assert(array_n[3] == 5, "Incorrect values from make_array_n.");

    constexpr auto array_non_copyable = make_array_n<1>(non_copyable{});
    static_assert(array_non_copyable.size() == 1, "Incorrect array size of 1 for move-only types.");

    constexpr auto array_empty = make_array_n<0>(2);
    static_assert(array_empty.empty(), "Incorrect array size for empty array.");

    constexpr auto array_non_copyable_empty = make_array_n<0>(non_copyable{});
    static_assert(array_non_copyable_empty.empty(), "Incorrect array size for empty array of move-only.");
}
person David Stone    schedule 03.12.2015
comment
Ваш тип non_copyable фактически можно скопировать с помощью operator=. - person Hertz; 20.02.2016
comment
@Hertz: явное использование конструктора перемещения по умолчанию приводит к неявному удалению операторов присваивания копирования и перемещения. Однако для этого тестового примера это не имеет значения, поскольку здесь нет назначений. - person David Stone; 14.06.2021

Другой способ инициализации массива общим значением - это фактическое создание списка элементов в серии определений:

#define DUP1( X ) ( X )
#define DUP2( X ) DUP1( X ), ( X )
#define DUP3( X ) DUP2( X ), ( X )
#define DUP4( X ) DUP3( X ), ( X )
#define DUP5( X ) DUP4( X ), ( X )
.
.
#define DUP100( X ) DUP99( X ), ( X )

#define DUPx( X, N ) DUP##N( X )
#define DUP( X, N ) DUPx( X, N )

Инициализировать массив до общего значения можно легко:

#define LIST_MAX 6
static unsigned char List[ LIST_MAX ]= { DUP( 123, LIST_MAX ) };

Примечание: DUPx введен для включения подстановки макросов в параметрах DUP

person Steen    schedule 23.07.2014

В случае массива однобайтовых элементов вы можете использовать memset, чтобы установить для всех элементов одно и то же значение.

Пример можно найти здесь.

person Steve Melnikoff    schedule 01.07.2009

1) Когда вы используете инициализатор для такой структуры или массива, неопределенные значения по существу создаются по умолчанию. В случае примитивного типа, такого как ints, это означает, что они будут обнулены. Обратите внимание, что это применяется рекурсивно: у вас может быть массив структур, содержащих массивы, и если вы укажете только первое поле первой структуры, тогда все остальные будут инициализированы нулями и конструкторами по умолчанию.

2) Компилятор, вероятно, сгенерирует код инициализатора, который, по крайней мере, настолько хорош, насколько вы могли бы сделать вручную. Я предпочитаю, чтобы компилятор выполнял инициализацию за меня, когда это возможно.

person Boojum    schedule 30.06.2009
comment
1) Инициализация POD по умолчанию здесь не происходит. Используя список, компилятор сгенерирует значения во время компиляции и поместит их в специальный раздел ассемблера, который просто загружается как часть инициализации программы (например, код). Таким образом, стоимость во время выполнения равна нулю. - person Martin York; 01.07.2009
comment
Я не понимаю, где он не прав? int a [100] = {} обязательно инициализируется значением 0, независимо от того, где он появляется, и struct {int a; } b [100] = {}; это слишком. по существу построено по умолчанию = ›значение построено, хотя. Но это не имеет значения в случае целых чисел, PODS или типов с объявленными пользователем ctors. Насколько я знаю, это имеет значение только для NON-Pods без заявленных пользователем ctors. Но из-за этого я бы не стал голосовать против (!). в любом случае, +1 для вас, чтобы снова сделать 0 :) - person Johannes Schaub - litb; 01.07.2009
comment
@Evan: Я уточнил свое утверждение с помощью Когда вы используете инициализатор ... Я не имел в виду неинициализированные значения. @Martin: Это может работать для постоянных, статических или глобальных данных. Но я не понимаю, как это будет работать с чем-то вроде: int test () {int i [10] = {0}; int v = я [0]; я [0] = 5; вернуть v; } Компилятору лучше инициализировать i [] нулями каждый раз, когда вы вызываете test (). - person Boojum; 01.07.2009
comment
он может помещать данные в сегмент статических данных и заставлять меня ссылаться на него :) - person Johannes Schaub - litb; 01.07.2009
comment
Верно - технически в этом случае он также может полностью исключить i и просто вернуть 0. Но использование статического сегмента данных для изменяемых данных было бы опасно в многопоточных средах. В ответ на вопрос Мартина я пытался просто сказать, что нельзя полностью исключить стоимость инициализации. Конечно, скопируйте готовый фрагмент из сегмента статических данных, но это все еще не бесплатно. - person Boojum; 01.07.2009

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

person ingomueller.net    schedule 13.03.2014

В языке программирования C ++ V4 Страуструп рекомендует использовать векторы или valarrays вместо встроенных массивов. Создавая valarrary, вы можете присвоить им определенное значение, например:

valarray <int>seven7s=(7777777,7);

Для инициализации массива длиной 7 элементов с «7777777».

Это способ реализации ответа на языке C ++ с использованием структуры данных C ++ вместо «простого старого массива C».

Я переключился на использование valarray как попытку в своем коде попытаться использовать C ++ isms v. Cism ....

person Astara    schedule 14.05.2014
comment
Это второй худший пример использования шрифта, который я когда-либо видел ... - person Steazy; 05.02.2018

Должно быть стандартной функцией, но по какой-то причине она не включена ни в стандартные C, ни в C ++ ...

#include <stdio.h>

 __asm__
 (
"    .global _arr;      "
"    .section .data;    "
"_arr: .fill 100, 1, 2; "
 );

extern char arr[];

int main() 
{
    int i;

    for(i = 0; i < 100; ++i) {
        printf("arr[%u] = %u.\n", i, arr[i]);
    }
}

В Фортране вы могли:

program main
    implicit none

    byte a(100)
    data a /100*2/
    integer i

    do i = 0, 100
        print *, a(i)
    end do
end

но в нем нет беззнаковых чисел ...

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

#include <stdio.h>
#include <stdint.h>

/* did I count it correctly? I'm not quite sure. */
uint8_t arr = {
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
};    

int main() 
{
    int i;

    for(i = 0; i < 100; ++i) {
        printf("arr[%u] = %u.\n", i, arr[i]);
    }
}

Что, если бы это был массив из 1 000 000 байт? Мне нужно было бы написать сценарий, чтобы написать его для меня, или прибегнуть к хакам со сборкой / и т. Д. Это нонсенс.

Он прекрасно переносится, нет никаких причин, чтобы его не было на языке.

Просто взломайте его, как:

#include <stdio.h>
#include <stdint.h>

/* a byte array of 100 twos declared at compile time. */
uint8_t twos[] = {100:2};

int main()
{
    uint_fast32_t i;
    for (i = 0; i < 100; ++i) {
        printf("twos[%u] = %u.\n", i, twos[i]);
    }

    return 0;
}

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

#!/usr/bin/perl
use warnings;
use strict;

open my $inf, "<main.c";
open my $ouf, ">out.c";

my @lines = <$inf>;

foreach my $line (@lines) {
    if ($line =~ m/({(\d+):(\d+)})/) {
        printf ("$1, $2, $3");        
        my $lnew = "{" . "$3, "x($2 - 1) . $3 . "}";
        $line =~ s/{(\d+:\d+)}/$lnew/;
        printf $ouf $line;
    } else {
        printf $ouf $line;
    }
}

close($ouf);
close($inf);
person Dmitry    schedule 03.04.2016
comment
вы печатаете в цикле, почему вы не можете назначить в цикле? - person Abhinav Gauniyal; 13.01.2017
comment
назначение внутри цикла влечет за собой накладные расходы времени выполнения; тогда как жесткое кодирование буфера является бесплатным, потому что буфер уже встроен в двоичный файл, поэтому он не тратит время на создание массива с нуля при каждом запуске программы. вы правы, что печать в цикле в целом не является хорошей идеей, лучше добавить внутри цикла, а затем распечатать один раз, поскольку каждый вызов printf требует системного вызова, тогда как конкатенация строк с использованием кучи / стека приложения - нет. Поскольку размер в программах такого типа не является проблемой, лучше создавать этот массив во время компиляции, а не во время выполнения. - person Dmitry; 13.01.2017
comment
назначение внутри цикла влечет за собой накладные расходы времени выполнения - вы сильно недооцениваете оптимизатор. - person Asu; 02.05.2017
comment
В зависимости от размера массива gcc и clang будут жестко закодировать или обмануть значение, а с большими массивами напрямую просто memset, даже с жестко запрограммированным массивом. - person Asu; 02.05.2017
comment
На некоторой цели компилятор поместит массив, созданный во время выполнения, в ram, и, более того, вы не можете объявить массив как const. В таких случаях было бы неплохо инициализировать заливку ... - person hl037_; 17.07.2020