Относительно инициализации 2-го массива в C ++ - PullRequest
0 голосов
/ 31 августа 2011

Я получаю смешанные ответы на этот вопрос по инициализации 2-го массива в C ++.

Вот сценарий:

class MyClass {
   private:
      static char my2dArray[10][20];
}; 

char MyClass::my2dArray[10][20] = {{0}};

Теперь это инициализирует все элементы этого массива с 0?

Кроме того, если у меня есть следующее определение типа:

typedef unsigned char u8;

и этот массив static u8 my2dArray[10][20], будет ли работать та же инициализация?

Предполагается, что все элементы явно инициализированы равными 0.

Ответы [ 2 ]

3 голосов
/ 31 августа 2011

Теперь это инициализирует все элементы этого массива с 0?

Да
Если список инициализаторов не имеет того же количества элементов, что и фактический массив.Тогда массив будет заполнен нулями.

будет ли работать та же инициализация?

Да
Здесь работают те же процессы.

2 голосов
/ 31 августа 2011
class MyClass {
   private:
     static char my2dArray[10][20];
}; 

char MyClass::my2dArray[10][20] = {{0}};

Теперь это инициализирует все элементы этого массива с 0?

Сортировка.

Напомним, что элементы вашего массива не char, но char[10] (что не может быть 0).

Здесь вы инициализируете внешний массив, предоставляя инициализатор для first внутреннего массива (* 1015)*, снова устанавливая только первый элемент внутреннего массива на 0).

Затем вы позволяете неявной инициализации по умолчанию вступить во владение для последующих элементов в обоих массивах.

[n3290: 8.5.1/1]: Агрегат является массивом или классом (раздел 9) без пользовательских конструкторов (12.1), без brace-or-equal-initializer для нестатических элементов данных (9.2), без личных или защищенных нестатических элементов данных (пункт 11), без базовых классов (пункт 10) и без виртуальных функций.

[n3290: 8.5.1/2]: Когда агрегат инициализируется списком инициализаторов, как указано в 8.5.4, элементы списка инициализаторов принимаются в качестве инициализаторов для элементов агрегата в порядке возрастания индекса или порядка элементов .Каждый элемент инициализируется копией из соответствующего initializer-clause .Если initializer-clause является выражением и требуется сужающее преобразование (8.5.4), чтобы преобразовать выражение, программа некорректна.[ Примечание : Если initializer-clause сам по себе является списком инициализатора, элемент инициализируется списком, что приведет к рекурсивному применению правил в этом разделе, еслиэлемент является совокупным. - конечная заметка ]

[n3290: 8.5.1/7:] Если в списке меньше инициализаторов-пунктов , чем членов всовокупность, то каждый элемент, не инициализированный явно, должен быть инициализирован из пустого списка инициализаторов (8.5.4).

[n3290: 8.5.4/3:] [..] В противном случае, если список инициализаторовне имеет элементов, объект инициализируется значением. [..]

Стандарт [final draft] фактически содержит ненормативный пример подобного поведения:

[n3290: 8.5.1/10]: [..] [ Пример: [..] С другой стороны,

float y[4][3] = { { 1 }, { 2 }, { 3 }, { 4 } };

инициализирует первый столбец y (рассматривается какдвумерный массив) и остаток равен нулю. - конец примера ]

Так что, в конечном итоге, да.Все ваши самые внутренние элементы массива будут содержать значение 0;просто ваш {{0}} на самом деле не слишком много сделал для этого.


Предполагается, что все элементы явно инициализированы равными 0.

Ну, так как ваш массив имеет static длительность хранения, его память все равно будет инициализироваться нулем, так что в конечном итоге бесполезно беспокоиться о себе.


Кроме того, если яимеют следующее определение типа:

typedef unsigned char u8;

и этот массив static u8 my2dArray[10][20], будет ли работать та же инициализация?

Да.Псевдоним типа ничего не меняет: этот массив имеет точно такой же тип (и продолжительность хранения), что и первый, и применяются те же правила.

...