close
Пространства имён
Варианты
Действия

Инициализация

Материал из cppreference.com

Объявление объекта может предоставлять его начальное значение с помощью процесса, известного как инициализация.

Для каждого объявления инициализатор, если не опущен, может быть одним из следующих:

= выражение (1)
= { список-инициализации } (2)
= { } (3) (начиная с C23)

где список-инициализации это непустой разделённый запятыми список инициализатор ов (с опциональной запятой в конце), причём каждый инициализатор имеет одну из трёх возможных форм:

выражение (1)
{ список-инициализации } (2)
{ } (3) (начиная с C23)
список-обозначений = инициализатор (4) (начиная с C99)

где список-обозначений это список обозначений массивов в форме [ константное-выражение ] или обозначения структуры/объединения в форме . идентификатор ; см. инициализацию массивов и инициализацию структур.

Замечание: среди инициализаторов в скобах может встречаться список-инициализации в составных литералах, являющихся выражениями в форме:

( тип ) { список-инициализации }
( тип ) { } (начиная с C23)
(начиная с 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 неопределённым значением
    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++ по инициализации