Поделиться через


Инициализация скалярных типов

При инициализации скалярных типов значение 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.

См. также

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