Инициализация скалярных типов
При инициализации скалярных типов значение assignment-expression
переменной назначается переменной. Применяются правила преобразования для присваивания. (См. сведения о правилах преобразования в статье Преобразования типов (C).)
Синтаксис
declaration
:
declaration-specifiers
необ.init-declarator-list
;
declaration-specifiers
:
storage-class-specifier
declaration-specifiers
необ.
type-specifier
declaration-specifiers
необ.
type-qualifier
declaration-specifiers
необ.
init-declarator-list
:
init-declarator
init-declarator-list
,
init-declarator
init-declarator
:
declarator
declarator
=
initializer
/* Для скалярной инициализации */
initializer
:
assignment-expression
Вы можете инициализировать переменные любого типа, если соблюдать следующие правила:
Переменные, объявленные на уровне области файлов, можно инициализировать. Если вы явно не инициализируете переменную на внешнем уровне, она инициализирована до 0 по умолчанию.
Константное выражение можно использовать для инициализации любой глобальной переменной, объявленной с использованием описателя
static
storage-class-specifier
. Переменные, объявленные какstatic
, инициализируются в начале исполнения программы. Если вы явно не инициализируете глобальнуюstatic
переменную, она инициализирована до 0 по умолчанию, и каждый элемент с типом указателя назначается пустым указателем.Переменные, объявленные с
auto
помощью описателя класса хранилища,register
инициализированы каждый раз, когда элемент управления выполнением передается в блок, в котором они объявлены. Если не включать инициализатор в объявление переменнойauto
илиregister
, начальное значение переменной будет неопределенным. Для автоматических и регистрирующих значений инициализатор не ограничивается константой; это может быть любое выражение, включающее ранее определенные значения, даже вызовы функций.Начальные значения для объявлений внешних переменных и для всех переменных
static
(как внешних, так и внутренних) должны представлять собой константные выражения. (Дополнительные сведения см. в разделе Константные выражения.) Так как адрес любой внешней объявленной или статической переменной является константой, ее можно использовать для инициализации внутренне объявленнойstatic
переменной указателя. Однако адрес переменнойauto
нельзя использовать в качестве статического инициализатора, так как он может отличаться для каждого выполнения блока. Для инициализации переменныхauto
иregister
можно использовать константные или переменные значения.Если объявление идентификатора имеет область блокировки, а идентификатор имеет внешнюю компоновку, объявление не может иметь инициализацию.
Примеры
Инициализация иллюстрируется следующими примерами.
int x = 10;
Целочисленная переменная x
инициализируется с константным выражением 10
.
register int *px = 0;
Указатель px
инициализируется значением 0, создавая указатель null.
const int c = (3 * 1024);
В этом примере используется константное выражение (3 * 1024)
для инициализации c
в константное значение, которое невозможно изменить из-за ключевого const
слова.
int *b = &x;
Этот оператор инициализирует указатель b
адресом другой переменной, x
.
int *const a = &z;
Указатель a
инициализируется с адресом переменной с именем z
. Тем не менее, так как она указана const
, переменная a
может быть инициализирована только инициализирована, никогда не изменяя. Она всегда указывает на одно и то же расположение.
int GLOBAL ;
int function( void )
{
int LOCAL ;
static int *lp = &LOCAL; /* Illegal initialization */
static int *gp = &GLOBAL; /* Legal initialization */
register int *rp = &LOCAL; /* Legal initialization */
}
Глобальная переменная GLOBAL
объявляется на внешнем уровне и поэтому имеет глобальное время существования. Локальная переменная имеет auto
класс хранилища и имеет адрес только во время выполнения функцииLOCAL
, в которой она объявлена. Поэтому попытка инициализировать static
переменную lp
указателя с адресом LOCAL
не разрешена. Переменную указателя static
gp
можно инициализировать с использованием адреса GLOBAL
, так как он всегда остается неизменным. Аналогично, *rp
можно инициализировать, так как переменная rp
является локальной и может иметь неконстантный инициализатор. Всякий раз при входе в блок LOCAL
имеет новый адрес, который затем присваивается rp
.