Я был очень удивлен, когда увидел это обозначение. Что он делает и что такое понятие C?
Что означает "int * a = (int [2]) {0, 2}; точно делаете?
Ответ 1
Это сложный литерал, определенный в разделе 6.5.2.5 стандарта C99.
Это не часть языка С++, поэтому неудивительно, что компиляторы С++ не компилируют его. (или компиляторы Java или Ada, если на то пошло)
Значение составного литерала - это имя неназванного объекта, инициализированного список инициализаторов. Если составной литерал происходит вне тела функции, объект имеет статическую продолжительность хранения; в противном случае он имеет автоматическую продолжительность хранения, связанную с закрывающий блок.
Нет, это не разрушит стек. Компилятор выделяет хранилище для объекта.
Скобки скопированы вокруг типа, и за ним следует список инициализаторов - это не листинг, так как список голых инициализаторов не имеет смысла в синтаксисе C99; вместо этого это постфиксный оператор, применяемый к типу, который дает объект данного типа. Вы не создаете { 0, 3 }
и отбрасываете его в массив, вы инициализируете int[2]
со значениями 0 и 3.
Что касается того, почему он используется, я не вижу достаточной причины для этого в вашей отдельной строке, хотя может быть, что можно переназначить, чтобы указать на какой-либо другой массив, и поэтому это более короткий способ сделать первый две строки:
int default_a[] = { 0, 2 };
int *a = default_a;
if (some_test) a = get_another_array();
Я нашел полезным использовать временные объединения для функций
// fills an array of unions with a value
kin_array_fill ( array, ( kin_variant_t ) { .ref = value } )
Ответ 2
Это конструкция c99, называемая составным литералом.
Из майского проекта 2005 года в разделе 6.5.2.5:
Постфиксное выражение, состоящее из имя в скобках, за которым следует скопированный список инициализаторов является составным литералом. Он обеспечивает неназванный объект, значение которого задается формулой список инициализаторов.
...
ПРИМЕР 1 Определение области файла
int *p = (int []){2, 4};
инициализирует p чтобы указать на первый элемент массив из двух целых чисел, первый из которых имеет значение два, а второе, четыре. Выражения в этом соединении литерал должен быть постоянным. Неименованный объект имеет статическое хранилище длительность.
Ответ 3
- Выделяет в стеке пространство для [массива] двух
int
s. - Задает [массив] двух
int
значениями0
и2
соответственно. - Объявляет локальную переменную типа
int*
и присваивает этой переменной адрес [массива] двухint
s.
Ответ 4
(int [2]) сообщает компилятору, что следующее выражение должно быть записано в int [2]. Это необходимо, так как {0, 2} может быть отлито для разных типов, например long [2]. Листинг происходит во время компиляции - не время выполнения.
Все выражение создает массив в памяти и устанавливает a для указания на этот массив.
Ответ 5
-
{0, 2}
- это обозначение для массива, состоящего из 0 и 2. -
(int[2])
выводит его в массив (не знаю почему). -
int * a =
присваивает его указателю int a.