Как во время компиляции инициализация переменных работает внутренне в c? - PullRequest
3 голосов
/ 09 июня 2019

Инициализация во время компиляции происходит только тогда, когда мы присваиваем значение переменной во время объявления переменной. Чтобы быть более конкретным, В чем разница между инициализацией переменной во время объявления int a=2 и после объявления int a; a=2?

Ответы [ 2 ]

4 голосов
/ 09 июня 2019

В чем разница между инициализацией переменной во время объявления int a=2 и после объявления int a; a=2?

Разница в том, что второй не является инициализацией . Это назначение . Когда дело доходит до вашего очень простого примера, на практике нет никакой разницы.

структуры и массивы

Большая разница в том, что некоторые приемы инициализации недоступны при обычных назначениях. Как например инициализация массива и структуры.

int x[5] = {1, 2, 3, 4, 5}; // Ok
x = {1, 2, 3, 4, 5}; // Not ok

struct myStruct {
    int x;
    char y;
};

struct myStruct a = {1, 'e'}; // Ok
a = {1, 'e'}; // Not ok
a = (struct myStruct) {1, 'e'}; // But this is ok

постоянные переменные

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

const int x = 5; // Ok
x = 3; // Not ok, x is declared as const

статические переменные

Это также влияет на статические переменные особым образом.

void foo() {
    static int x = 5; // The initialization will only be performed once
    x = 8; // Will be performed everytime the fuction is called

Таким образом, эта функция вернет 1, если она была вызвана ранее, и 0 в противном случае:

int hasBeenCalled() {
    static int ret = 0;
    if(!ret) {
        ret = 1;
        return 0;
    }
    return 1;
}

Вы можете прочитать об инициализации в главе 6.7.9 в стандарте C. Задания находятся в главе 6.5.16

2 голосов
/ 09 июня 2019

Стандарт не определяет инициализацию во время компиляции. Это зависит от среды, в которой разрабатывается и выполняется ваш код.

Способ инициализации переменных зависит от продолжительности их хранения. Вы не упомянули об этом.

Инициализированные автоматические переменные будут записываться при каждом достижении их объявления. Так что показанная вами разделенная версия не будет иметь никакого значения.

Статические переменные всегда инициализируются и только один раз перед запуском программы. Таким образом, ваша разделенная версия не является инициализацией и выполняется каждый раз, когда выполняется задание.

Примеры из реального мира:

Большинство (если не все) компьютерные системы хранят начальные значения явно (а не нулевых) инициализированных статических переменных в специальном разделе, называемом data, который загружается загрузчиком системы в ОЗУ. Таким образом, эти переменные получают свои значения до запуска программы. Статические переменные, не инициализированные явно или имеющие нулевые значения, помещаются в секцию bss и заполняются нулями кодом запуска перед запуском программы.

Многие встроенные системы имеют свою программу в энергонезависимой памяти, которую нельзя изменить. В таких системах код запуска копирует начальные значения раздела data в выделенное ему пространство в ОЗУ, что приводит к аналогичному результату. Тот же код запуска обнуляет и раздел bss.

Примечание 1: разделы не обязательно должны называться так. Но это обычное дело.

Примечание 2: Существуют другие виды продолжительности хранения, см. Главу 6.2.4 стандарта.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...