g ++ предупреждение об объявлении многомерного двойного массива - PullRequest
1 голос
/ 23 августа 2011

В моей программе на C ++ я пытаюсь инициализировать массив 3 * 3 * 3 типа double со всеми 0. В заголовочном файле класса я объявил член

double list[3][3][3];

Когда я распечатал содержимое этого массива, я обнаружил, что не все записи равны 0, как я ожидал. например список [1] ​​[1] [1] имеет значение 4.03158e-321

Следовательно, я вручную инициализировал этот массив для всех 0 в конструкторе:

list = {{{0,0,0},{0,0,0},{0,0,0}},
      {{0,0,0},{0,0,0},{0,0,0}},
      {{0,0,0},{0,0,0},{0,0,0}}};

Это заставляет мою программу работать, однако я получил предупреждение компилятора:

warning: extended initializer lists only available with -std=c++0x or -std=gnu++0x

Поэтому мой вопрос

  1. Почему список имеет ненулевые записи после инициализации в заголовок
  2. Почему я получаю вышеуказанное предупреждающее сообщение и как от него избавиться?

Мой компилятор - g ++ (Ubuntu / Linaro 4.5.2-8ubuntu4) 4.5.2, с gcc версии 4.5.2 (Ubuntu / Linaro 4.5.2-8ubuntu4)

Ответы [ 5 ]

5 голосов
/ 23 августа 2011

В C ++ 03 вы можете использовать эту инициализацию только при определении массива:

double list[3][3][3] = {{{0,0,0},{0,0,0},{0,0,0}},
                        {{0,0,0},{0,0,0},{0,0,0}},
                        {{0,0,0},{0,0,0},{0,0,0}}};

Компилятор предупреждает, что в соответствии с текущим стандартом он не должен принимать ваш код, даже если он можетобработать его, применяя предстоящие стандартные правила, где {...} называется external-initializer .

В этом конкретном случае, когда массив является членом, и вы хотите инициализироватьдля всех нулей, вы можете просто использовать значение-инициализацию в C ++ 0x:

struct test { 
   double list[3][3][3];
   test() : list()
   {}
};

Для членов типов POD (которые представляют собой массив double),приведенный выше синтаксис (list()) в списке инициализаторов означает, что элемент должен инициализироваться значением , что фактически означает, что все значения будут установлены в 0

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

Я что-то упустил или вы не можете просто сделать

class Class {
public:
    double array[3][3][3];

    Class() : array() { }
};
2 голосов
/ 23 августа 2011
  1. В шапке он не инициализирован, он просто объявлен.Встроенные типы (и более того, в общем случае POD) не инициализируются нулями автоматически, если они не являются глобальными (на самом деле они имеют длительность статической памяти ) по соображениям производительности (как и во многих других случаях в C ++, инициализация является опцией-in, вы платите за него, только если вам это нужно).

  2. Этот синтаксис действителен только при инициализации массива, в то время как эта инструкция является присваиванием .Этот синтаксис может быть использован во многих других местах в новом стандарте C ++ (ранее C ++ 0x, теперь C ++ 11, поскольку он только что был утвержден).

В моемПо нашему мнению, самый быстрый способ решить вашу проблему - это просто:

double * firstElem=&list[0][0][0];
std::fill(firstElem, firstElem+27, 0.);

, который обрабатывает list как одномерный массив из 27 double с и заполняет его нулями (подробнее об этом трюке здесь ).

Обратите внимание, что этот аргумент также кратко рассматривается в массиве FAQ .

1 голос
/ 23 августа 2011

Есть более простой способ сделать это.Следующее должно работать в C или C ++, только для инициализации переменной (т.е. не в присваивании):

double list[3][3][3] = {0};

{0} - это специальный инициализатор, который устанавливает практически любую структуру на все нули.

0 голосов
/ 23 августа 2011

Почему бы не установить значения в ноль с помощью memset или цикла?

...