Spec-Zone.ru › C

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

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

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

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

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

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

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

Примечание: помимо инициализаторов, заключённые в фигурные скобки список_инициализаторов могут встречаться в сложных литералах, которые являются выражениями вида:

( тип ) { список_инициализаторов }
( тип ) { } (с C23)
(с C99)

Объяснение

Инициализатор задаёт начальное значение, хранящееся в объекте.

Явная инициализация

Если инициализатор указан, см.

  • скалярную инициализацию для инициализации скалярных типов
  • инициализацию массивов для инициализации массивов
  • инициализацию структур для инициализации структур и объединений.

Неявная инициализация

Если инициализатор не указан:

  • объекты с автоматическим временем жизни инициализируются неопределёнными значениями (которые могут быть ошибочными представлениями)
  • объекты со статическим и локальным для потока временем жизни инициализируются пустым значением

Пустая инициализация

Объект инициализируется пустым значением, если он явно инициализируется из инициализатора = {}.

(с C23)

В некоторых случаях объект инициализируется пустым значением, если он не инициализируется явно, то есть:

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

Примечания

При инициализации объекта со статическим или локальным для потока временем жизни, каждое выражение в инициализаторе должно быть константным выражением или строковой константой.

Инициализаторы не могут использоваться в объявлениях объектов неполного типа, VLAs и объектов области блока с связью.

Начальные значения параметров функций устанавливаются так, как если бы они были присвоены из аргументов вызова функции, а не путём инициализации.

Если неопределённое значение используется в качестве аргумента для любого вызова стандартной библиотеки, поведение не определено. В противном случае результат любого выражения, содержащего неопределённые значения, является неопределённым значением (например, int n;, n не могут сравниться сами с собой и, похоже, могут изменить своё значение при последующих чтениях)

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

(до C23)

Пустой инициализатор = {} (или (T){} в сложных литералах) может использоваться для достижения той же семантики, что и инициализация значением в C++.

(с C23)

Пример

#include <stdlib.h>
int a[2]; // initializes a to {0, 0}
int main(void)
{
    int i;          // initializes i to an indeterminate value
    static int j;   // initializes j to 0
    int k = 1;      // initializes k to 1
 
    // initializes int x[3] to 1,3,5
    // initializes int* p to &x[0]
    int x[] = { 1, 3, 5 }, *p = x;
 
    // initializes w (an array of two structs) to
    // { { {1,0,0}, 0}, { {2,0,0}, 0} }
    struct {int a[3], b;} w[] = {[0].a = {1}, [1].a[0] = 2};
 
    // function call expression can be used for a local variable
    char* ptr = malloc(10);
    free(ptr);
 
//  Error: objects with static storage duration require constant initializers
//  static char* ptr = malloc(10);
 
//  Error: VLA cannot be initialized
//  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++ по Инициализации

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/c/language/initialization

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API