How are local and global variables initialized by default?

Based on below, am i right?

  • global_A reference is initialized to null.
  • global_int is 0
  • local_A reference is null
  • local_int is uninitialized
  • Both global_A.x and local_A.x is uninitialized.

THanks for any help.


A global_A;
int global_int;

class A {
  public : int x;
}

int main()
{
  int local_int;
  A local_A;
}
10
задан kiamlaluno 24 August 2010 в 05:34
поделиться

10 ответов

В вашем коде нет ссылок, поэтому любые ваши пункты, в которых упоминаются «ссылки», не имеют смысла.

В вашем примере оба глобальных объекта - global_int и global_A - инициализируются нулем. Оба локальных объекта - local_int и local_A - содержат неопределенные значения, что означает, что local_int и local_A.x не инициализированы.

P.S. Конечно, как уже отмечалось, ваш код не компилируется. Вы не можете объявить объекты A до объявления класса A (и вам не хватает ; после определения класса).

7
ответ дан 3 December 2019 в 17:18
поделиться

Этот код не будет компилироваться, пока вы не переадресуете объявление A.

Ссылка global_A инициализируется значением null - Нет, она будет ссылаться на объект A. global_int равно 0 - Думаю, нужно проверить. Ссылка local_A равна нулю - нет, как и global_A. local_int не инициализирован - да, он получит какое-то мусорное значение. И global_A.x, и local_A.x не инициализированы - Да.

Вы всегда можете отладить и убедиться в этом сами.

-2
ответ дан 3 December 2019 в 17:18
поделиться

ссылка global_A инициализируется на нулевой.

Нет, это действительный объект (созданный на основе конструктора по умолчанию, которого нет в вашем коде, но компилятор добавляет его)

global_int равно 0

да

ссылка local_A равна нулю

нет, по той же причине, что и для global

local_int не инициализирован

нет, он инициализирован в 0

И global_A.x, и local_A.x являются неинициализированный.

нет, оба инициализируются значением 0

-3
ответ дан 3 December 2019 в 17:18
поделиться

Основываясь на ответе Андрея.

$ 3.6.2- «Объекты со статической продолжительностью хранения (3.7.1) должны быть инициализированы нулем (8.5) перед любой другой инициализацией.». В OP, global_A и global_int имеют статическую продолжительность хранения. "local_int" и "local_A" не связаны, поскольку это локальные объекты.

$ 8.5 / 5- Чтобы инициализировать объект типа T нулем, необходимо:

- если T является скалярным типом (3.9), объекту присвоено значение 0 (ноль) преобразован в T;

- если T - тип класса, не являющийся объединением, каждый нестатический член данных и каждый подобъект базового класса zeroinitialized;

- если T - тип объединения, объект первый названный элемент данных89) с нулевой инициализацией;

- если T тип массива, каждый элемент инициализируется нулем;

- если T - ссылочный тип, нет инициализация выполняется.

$ 6.7.4 / 4- "Нулевая инициализация (8.5) всех локальных объектов со статической продолжительностью хранения (3.7.1) выполняется до любой другой инициализации. Локальный объект типа POD (3.9) со статическим продолжительность хранения, инициализированная с помощью константных выражений, инициализируется до того, как его блок будет впервые введен. Реализации разрешено выполнять ранняя инициализация других локальных объектов со статической продолжительностью хранения при тех же условиях, при которых реализации разрешено статически инициализировать объект со статической продолжительностью хранения в области пространства имен (3.6.2). В противном случае такой объект инициализируется при первом прохождении управления через его объявление; такой объект считается инициализированным после завершения его инициализации. Если инициализация завершается выдачей исключения, инициализация не завершена, поэтому она будет повторена, когда в следующий раз элемент управления войдет в объявление. Если элемент управления повторно входит в объявление (рекурсивно) во время инициализации объекта, поведение не определено. "

РЕДАКТИРОВАТЬ 2:

$ 8.5 / 9- "Если инициализатор не указан для объекта, а объект имеет (возможно cv-квалификацию) тип класса не-POD (или его массив), объект должен быть инициализированный по умолчанию; если объект типа с квалификатором const, базовый тип класса должен иметь объявленный пользователем конструктор по умолчанию. В противном случае, если для нестатического объекта не указан инициализатор, объект и его подобъекты, если есть, иметь неопределенное начальное значение90) ; если объект или любой из его подобъекты имеют квалификацию const типа, программа имеет неправильный формат ».

В общем, вы хотите прочитать эти разделы вместе с 8,5 долл. США, чтобы надежно удержать этот аспект.

13
ответ дан 3 December 2019 в 17:18
поделиться

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

Типы языкового уровня (например, указатели, 'int', 'float', 'bool' и т. Д.) «Конструктор по умолчанию» абсолютно ничего не делает, он просто оставляет память в том виде, в котором она была объявлена ​​(глобальные / статические переменные являются частными случаями, см. ответ chubsdad для получения дополнительных сведений). Это означает, что они могут быть чем угодно, потому что вы обычно не можете быть уверены в том, что было в этой памяти ранее или даже откуда она взялась (кроме случая с оператором «размещение нового»).

Созданный вами класс не имеет конструкторов, поэтому компилятор сгенерирует для вас конструктор по умолчанию, который просто вызывает конструктор каждого из своих членов / переменных. Если вы включите информацию, представленную в предыдущем абзаце, вы увидите, что для переменной 'x' будет вызван конструктор по умолчанию, который ничего не делает и, следовательно, не инициализируется никаким значением.

Как уже говорили другие, в вашем коде нет ссылок или указателей, поэтому термин «NULL» здесь недопустим во всех случаях. NULL обычно относится к указателю, который, как и другие типы языковых уровней, ничего не устанавливает, пока вы не присвоите ему значение (если, конечно, это глобальная / статическая переменная).

7
ответ дан 3 December 2019 в 17:18
поделиться

Для полноты картины, если у вас есть ссылки:

Ссылки должны быть инициализированы при объявлении, иначе вы получите наказание из-за ошибки компилятора. Это означает, что для ссылки всегда требуется другое значение или ссылка, на которую она ссылается (например, говорит), это обеспечивается компилятором, поэтому вы не можете ее забыть. Это также означает, что ссылки никогда не могут быть нулевыми указателями. Однако объект, на который они ссылаются, может стать недействительным.

3
ответ дан 3 December 2019 в 17:18
поделиться

global_A и local_A не являются ссылками; они являются объектами и созданы с использованием конструкторов по умолчанию. Конструктор по умолчанию не указан, поэтому он будет сгенерирован, но ничего не сделает, поэтому переменная-член останется неинициализированной.

1
ответ дан 3 December 2019 в 17:18
поделиться
A global_A;

Это экземпляр, а не указатель, ваша программа вызовет конструктор перед входом в main.

Чтобы получить указатель на экземпляр, а не на экземпляр, вы должны написать:

A* global_A;

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

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

Как и раньше, если вам нужен указатель на A, вы должны написать A * local_A, но на этот раз вы должны сами инициализировать его значением NULL.

A *local_A = NULL;

Вариал local_int не будет инициализирован, так как это примитивный тип.

Если инициализация local_A.x зависит от конструктора A, конструктор по умолчанию не будет инициализировать local_A.x. Если x, где экземпляр класса, создающий экземпляр A, инициализирует x конструктором своего класса.

1
ответ дан 3 December 2019 в 17:18
поделиться

ну, ребята ... я еще больше запутался, когда увидел ответы отсюда. В любом случае я провел тест, как показано ниже:

1 #include

  2 using namespace std;
  3 
  4 class A {
  5 
  6 public :
  7         A() : x(9) {};
  8         int x;
  9 
 10 };
 11 
 12 A global_a;
 13 int global_b;
 14 
 15 int main() {
 16 
 17         A local_a;
 18         int local_b;
 19         cout << "global_a.x = " << global_a.x << '\n';
 20         cout << "local_a.x = " << local_a.x << '\n';
 21 
 22         cout << "global_b = " << global_b << '\n';
 23         cout << "local_b = " << local_b << '\n';
 24 
 25 }

Результаты с использованием моего компилятора g ++ в ubuntu linux:

global_a.x = 9

local_a.x = 9

global_b = 0

​​local_b = 0

Я действительно думаю, что local_b должен быть неопределенным, но каким-то образом компилятор инициализировал его по умолчанию. Однако local_a .. я не уверен, нужно ли инициализировать его по умолчанию. Из тестирования здесь .. local_a кажется инициализированным. Не уверен, что это соответствует стандартной спецификации C ++ (например, в C ++ PRimer 4-го издания говорится, что конструктор по умолчанию используется независимо от того, где объявлена ​​переменная класса - означает ли это, что переменная типа класса инициализируется, является ли она глобальной или локальной?).

Что бы это ни было ... это адская неразбериха. Может мне стоит бросить изучать C ++. Java намного проще. Ад, даааа !!

-2
ответ дан 3 December 2019 в 17:18
поделиться

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

-2
ответ дан 3 December 2019 в 17:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: