Инициализация
Объявление объекта может предоставлять его начальное значение с помощью процесса, известного как инициализация.
Для каждого объявления инициализатор, если не опущен, может быть одним из следующих:
= выражение
|
(1) | ||||||||
= { список-инициализации }
|
(2) | ||||||||
= { }
|
(3) | (начиная с C23) | |||||||
где список-инициализации это непустой разделённый запятыми список инициализатор ов (с опциональной запятой в конце), причём каждый инициализатор имеет одну из трёх возможных форм:
| выражение | (1) | ||||||||
{ список-инициализации }
|
(2) | ||||||||
{ }
|
(3) | (начиная с C23) | |||||||
список-обозначений = инициализатор
|
(4) | (начиная с C99) | |||||||
|
где список-обозначений это список обозначений массивов в форме Замечание: среди инициализаторов в скобах может встречаться список-инициализации в составных литералах, являющихся выражениями в форме:
|
(начиная с C99) | ||||||||||||||||||||||||||||||||||||
Объяснение
Инициализатор определяет начальное значение, сохранённое в объекте.
Явная инициализация
Если инициализатор предоставлен, см.
- инициализацию скаляров по инициализации скалярных типов
- инициализацию массивов по инициализации типов массивов
- инициализацию структур по инициализации типов структур и объединений.
Неявная инициализация
Если инициализатор не предоставлен:
- объекты с автоматическим размещением инициализируются неопределёнными значениями (которые могут быть мнимыми представлениями)
- объекты со статическим и локальным для потоков рамещением имеют пустую инициализацию
Пустая инициализация
|
Объект имеет пустую инициализацию, если он имеет явный инициализатор вида |
(начиная с C23) |
В некоторых случаях объект имеет пустую инициализацию, если он не инициализирован явно, так что:
- указатели инициализируются нулевыми значениями своих типов
- объекты целых типов инициализируются беззнаковым нулём
- объекты вещественных типов инициализируются положительным нулём
- все элементы массивов, все элементы структур и первые элементы объединений имеют пустую инициализацию рекурсивно, а также все выравнивающие биты инициализируются нулями
- (на платформах, где значения нулевых указателей и вещественные нули имеют представление полностью нулевыми битами эта форма инициализации для статических объектов обычно реализуется их размещением в разделе .bss образа программы)
Замечания
При инициализации объекта статического или локального для потока класса памяти, каждое выражение в инициализаторе должно быть константным выражением или строковым литералом.
Инициализаторы не могут использоваться в объявлениях объектов неполного типа, массивах переменной длины и объектов в блоках с компоновкой.
Начальные значения параметров функции устанавливаются как если бы выполнилось присваивание из аргументов оператора вызова функции вместо инициализации.
Если используется неопределённое значение в качестве аргумента вызова любой функции из стандартной библиотеки, поведение не определено. Иначе результат любого выражения, включающего неопределённые значения (напр. int n;, n не может сравниваться на равенство с собой и может изменить своё значение при последующих чтениях)
|
В C не существует специальной конструкции, соответствующей инициализации значением в C++; однако вместо этого можно использовать |
(до C23) |
|
Пустой инициализатор |
(начиная с C23) |
Пример
#include <stdlib.h>
int a[2]; // инициализируется {0, 0}
int main(void)
{
int i; // инициализирует i неопределённым значением
static int j; // инициализирует j нулём
int k = 1; // инициализирует k единицей
// инициализирует int x[3] значениями 1,3,5
// инициализирует int* p значением &x[0]
int x[] = { 1, 3, 5 }, *p = x;
// инициализирует w (массив двух структур)
// { { {1,0,0}, 0}, { {2,0,0}, 0} }
struct {int a[3], b;} w[] = {[0].a = {1}, [1].a[0] = 2};
// выражение вызова функции может использоваться для локальной переменной
char* ptr = malloc(10);
free(ptr);
// Ошибка: статические объекты требуют константные инициализаторы
// static char* ptr = malloc(10);
// Ошибка: массив переменной длины не может быть инициализирован
// int vla[n] = {0};
}
Ссылки
- Стандарт C17 (ISO/IEC 9899:2018):
- 6.7.9 Инициализация (стр. 100-105)
- Стандарт C11 (ISO/IEC 9899:2011):
- 6.7.9 Инициализация (стр. 139-144)
- Стандарт C99 (ISO/IEC 9899:1999):
- 6.7.8 Инициализация (стр. 125-130)
- Стандарт C89/C90 (ISO/IEC 9899:1990):
- 6.5.7 Инициализация
См. также
Документация C++ по инициализации
|