Я пытаюсь инициализировать международный массив со всем набор в-1.
Я попробовал следующее, но это не работает. Это только устанавливает первое значение в-1.
int directory[100] = {-1};
Почему это не работает правильно?
Невозможно сделать то, что вы пытаетесь сделать с необработанным массивом (если вы явно не перечислите все 100 -1
в списке инициализаторов), вы можете сделайте это с помощью вектора
:
vector<int> directory(100, -1);
Кроме того, вы можете создать массив и установить значения на -1
, используя один из других упомянутых методов.
использовать вектор типа int вместо массива.
vector<int> directory(100,-1); // 100 ints with value 1
Работает правильно. Так работают инициализаторы списков.
Я считаю, что 6.7.8.10 стандарта C99 охватывает это:
Если объект, у которого есть автоматическая продолжительность хранения не инициализирована явно, его значение неопределенный.Если объект, имеющий статическая продолжительность хранения не инициализируется явно, затем:
- если он имеет тип указателя, он инициализируется нулевым указателем;
- если он имеет арифметический тип, он инициализируется (положительным или беззнаковым) ноль;
- если это агрегат, каждый член инициализируется (рекурсивно) в соответствии с к этим правилам;
- если это объединение, первый именованный член инициализируется (рекурсивно) согласно этим правилам.
Если вам нужно сделать все элементы в массиве одинаковыми ненулевыми значениями, вам придется использовать цикл или memset .
Также обратите внимание, что, если вы действительно не знаете, что делаете, векторы предпочтительнее массивов в C ++ :
Вот что вам нужно знать о контейнерах и массивах:
- Контейнер занятия делают программистов более продуктивными. Поэтому, если вы настаиваете на использовании массивов, в то время как окружающие готовы использовать классы-контейнеры, вы, вероятно, будете менее продуктивны, чем они (даже если вы умнее и опытнее, чем они!).
- Контейнерные классы позволяют программистам писать более надежный код. Поэтому, если вы настаиваете на использовании массивов, в то время как окружающие готовы использовать классы-контейнеры, ваш код, вероятно, будет содержать больше ошибок, чем их код (даже если вы умнее и опытнее).
- И если вы настолько умны и настолько опытны, что можете использовать массивы так же быстро и безопасно, как они могут использовать классы контейнеров, то кто-то другой, вероятно, в конечном итоге будет поддерживать ваш код и, вероятно, внесет ошибки.Или, что еще хуже, вы будете единственным, кто сможет поддерживать свой код, поэтому руководство оторвет вас от разработки и переведет на постоянную работу по обслуживанию - именно то, что вы всегда хотели!
В связанном вопросе есть гораздо больше; прочтите это.
Если у вас меньшее количество элементов, вы можете указать их один за другим. Инициализация массива работает путем указания каждого элемента, а не путем указания единственного значения, которое применяется для каждого элемента.
int x[3] = {-1, -1, -1 };
Вы также можете использовать вектор и использовать конструктор для инициализации всех значений. Позже вы можете получить доступ к буферу необработанного массива, указав & v.front ()
std::vector directory(100, -1);
. Есть способ сделать это, также используя memset
или другие подобные функции. memset
работает для каждого символа в указанном вами буфере, поэтому он будет работать нормально для таких значений, как 0
, но может не работать в зависимости от того, как хранятся отрицательные числа для -1
].
Вы также можете использовать STL для инициализации массива с помощью fill_n . Для универсального действия с каждым элементом вы можете использовать for_each.
fill_n(directory, 100, -1);
Или, если вы действительно хотите, вы можете пойти неубедительным путем, вы можете выполнить цикл for со 100 итерациями и выполнить directory [i] = -1;
Меня удивляют все ответы, предполагающие вектор
. Это даже не одно и то же!
Используйте std :: fill
, из
:
int directory[100];
std::fill(directory, directory + 100, -1);
Не касается непосредственно вопроса, но вам может понадобиться хорошая вспомогательная функция, когда дело касается массивов:
template <typename T, size_t N>
T* end(T (&pX)[N])
{
return pX + N;
}
Раздача:
int directory[100];
std::fill(directory, end(directory), -1);
Так что вам не нужно указывать размер дважды.
Если вам действительно нужны массивы, вы можете использовать класс boosts array. Его член assign выполняет эту работу:
boost::array<int,N> array; // boost arrays are of fixed size!
array.assign(-1);
Это действительно работает правильно. Ваши ожидания от инициализатора неверны. Если вы действительно хотите использовать этот подход, вам понадобится 100 -1, разделенных запятыми, в инициализаторе. Но что тогда произойдет, когда вы увеличите размер массива?
Я бы предложил использовать std :: array
. По трем причинам:
1. массив обеспечивает безопасность во время выполнения против выхода индекса за пределы в операциях индексации (то есть operator []
),
2. массив автоматически переносит размер без необходимости передавать его отдельно
3. И что наиболее важно, массив предоставляет метод fill ()
, который требуется для
эта проблема
#include <array>
#include <assert.h>
typedef std::array< int, 100 > DirectoryArray;
void test_fill( DirectoryArray const & x, int expected_value ) {
for( size_t i = 0; i < x.size(); ++i ) {
assert( x[ i ] == expected_value );
}
}
int main() {
DirectoryArray directory;
directory.fill( -1 );
test_fill( directory, -1 );
return 0;
}
Использование массива требует использования "-std = c ++ 0x" для компиляции (применимо к приведенному выше коду).
Если это недоступно или если это не вариант, тогда другие параметры, такие как std :: fill () (как предлагает GMan ) или ручное кодирование метода fill (), могут быть выбрал.