Инициализация
Объявление объекта может предоставлять его начальное значение с помощью процесса, известного как инициализация.
Для каждого объявления инициализатор, если не опущен, может быть одним из следующих:
= выражение | (1) | ||||||||
= { список-инициализации} | (2) | ||||||||
= { } | (3) | (начиная с C23) | |||||||
где список-инициализации это непустой разделённый запятыми список инициализатор ов (с опциональной запятой в конце), причём каждый инициализатор имеет одну из трёх возможных форм:
выражение | (1) | ||||||||
{ список-инициализации} | (2) | ||||||||
{ } | (3) | (начиная с C23) | |||||||
список-обозначений= инициализатор | (4) | (начиная с C99) | |||||||
где список-обозначений это список обозначений массивов в форме Замечание: среди инициализаторов в скобах может встречаться список-инициализации в составных литералах, являющихся выражениями в форме:
| (начиная с C99) |
Содержание |
[править]Объяснение
Инициализатор определяет начальное значение, сохранённое в объекте.
[править]Явная инициализация
Если инициализатор предоставлен, см.
- инициализацию скаляров по инициализации скалярных типов
- инициализацию массивов по инициализации типов массивов
- инициализацию структур по инициализации типов структур и объединений.
[править]Неявная инициализация
Если инициализатор не предоставлен:
- объекты с автоматическим размещением инициализируются неопределёнными значениями (которые могут быть мнимыми представлениями)
- объекты со статическим и локальным для потоков рамещением имеют пустую инициализацию
[править]Пустая инициализация
Объект имеет пустую инициализацию, если он имеет явный инициализатор вида ={}. | (начиная с C23) |
В некоторых случаях объект имеет пустую инициализацию, если он не инициализирован явно, так что:
- указатели инициализируются нулевыми значениями своих типов
- объекты целых типов инициализируются беззнаковым нулём
- объекты вещественных типов инициализируются положительным нулём
- все элементы массивов, все элементы структур и первые элементы объединений имеют пустую инициализацию рекурсивно, а также все выравнивающие биты инициализируются нулями
- (на платформах, где значения нулевых указателей и вещественные нули имеют представление полностью нулевыми битами эта форма инициализации для статических объектов обычно реализуется их размещением в разделе .bss образа программы)
[править]Замечания
При инициализации объекта статического или локального для потока класса памяти, каждое выражение в инициализаторе должно быть константным выражением или строковым литералом.
Инициализаторы не могут использоваться в объявлениях объектов неполного типа, массивах переменной длины и объектов в блоках с компоновкой.
Начальные значения параметров функции устанавливаются как если бы выполнилось присваивание из аргументов оператора вызова функции вместо инициализации.
Если используется неопределённое значение в качестве аргумента вызова любой функции из стандартной библиотеки, поведение не определено. Иначе результат любого выражения, включающего неопределённые значения (напр. int n;, n не может сравниваться на равенство с собой и может изменить своё значение при последующих чтениях)
В C не существует специальной конструкции, соответствующей инициализации значением в C++; однако вместо этого можно использовать ={0} (или (T){0} в составных литералах)(начиная с C99), так как стандарт C не разрешает пустые структуры, пустые объединения или массивы нулевой длины. | (до C23) |
Пустой инициализатор ={} (или (T){} в составных литералах) может использоваться для достижения той же семантики, как при инициализации значением в C++. | (начиная с C23) |
[править]Пример
#include <stdlib.h>int a[2];// инициализируется {0, 0}int main(void){int i;// инициализирует i неопределённым значениемstaticint 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++ по инициализации |