Вопрос о декларации в стиле фанк - PullRequest
2 голосов
/ 10 апреля 2011

Я только что натолкнулся на объявление этого массива:

const int nNums= 4;
int* nums[nNums] = {0, 0, 0}, d[nNums];

Я понимаю, что создается указатель на nums, но что за бизнес справа?d[] инициализируется, но я не совсем уверен, что делает {0,0,0}.

Ответы [ 4 ]

5 голосов
/ 10 апреля 2011

int* nums[nNums] = {0, 0, 0} определен массив из 4 целочисленных указателей, каждый из которых инициализирован значением NULL.Однако обратите внимание, что d - это массив целых и , а не целочисленных указателей, и эти значения не инициализируются.

3 голосов
/ 10 апреля 2011

Этот код эквивалентен:

const int nNums= 4;
int* nums[nNums] = {0, 0, 0};
int d[nNums];

Итак, nums - это массив int* с длиной 4, все четыре элемента которого инициализированы нулем;d - это массив int с длиной 4, со всеми четырьмя элементами неинициализирован (чтобы подчеркнуть: d не не инициализируется каким-либо образом).

Синтаксис = {0, 0, 0} в этом контексте известен как «агрегатная инициализация» и описан в §8.5.1 стандарта C ++ 03;соответствующая часть для этого кода (§8.5.1 / 2) гласит:

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

Итак, первые три элемента nums явно инициализируются в 0, а четвертый элемент неявно«значение инициализировано», как указано в §8.5.1 / 7:

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

Инициализация значения описана в §8.5 / 5:

К инициализация значения объекттипа T означает:

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

To инициализация нулями объект типа T означает:

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

Это приводит к тому, что четвертый элемент nums также инициализируется равным нулю.

1 голос
/ 10 апреля 2011
int* nums[nNums] = {0, 0, 0}, d[nNums];

Как @Asha уже говорила, что nums - это массив из 4 целочисленных указателей, каждый из которых инициализирован значением NULL.

Интересный вопрос, который можно задать здесь: каков типпеременная d?

Это массив из 4 целочисленных указателей?

Или

Это массив из 4 целых чисел?

Итак, ответ: это массив из 4 целых чисел.* связан только с первым объявленным символом nums.

Эквивалентное объявление будет следующим:

int* nums[nNums] = {0, 0, 0};
int d[nNums]; //not int* d[nNums];

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

int*  nums[nNums] = {0, 0, 0}, d[nNums];  //old one!
int  *nums[nNums] = {0, 0, 0}, d[nNums];  //new one. note the position of *
0 голосов
/ 10 апреля 2011

> Я понимаю, что указатель на числа создается,

Вы неправильно поняли. В этой декларации не создается указатель на nums. Декларация

int* nums[4] = {0, 0, 0};

объявляет массив из 4 указателей. nums сам по себе является массивом, а не указателем на что-либо.

> а что за бизнес справа?

Детали = {0, 0, 0} называются «агрегатным инициализатором». Инициализирует первые элементы дерева массива nums. Непонятно, почему только три явно инициализированы (в то время как четвертый оставлен для инициализации в ноль неявно ). Кроме того, в C ++ тот же эффект может быть достигнут с помощью

int* nums[4] = {};

декларация, где все четыре элемента инициализируются нулем неявно .

> d [] инициализируется

А? Нет. Декларация d эквивалентна

int d[4];

означает, что d вообще не инициализируется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...