Переменная инициализация в C++

Мое понимание то, что int переменная будет инициализирована к 0 автоматически; однако, это не. Код ниже печатает случайное значение.

int main () 
{   
    int a[10];
    int i;
    cout << i << endl;
    for(int i = 0; i < 10; i++)
        cout << a[i] << " ";
    return 0;
}
  • Какие правила, если таковые имеются, относятся к инициализации?
  • А именно, при каких условиях переменные инициализируются автоматически?
42
задан FluxLemur 26 July 2017 в 17:44
поделиться

8 ответов

Он будет автоматически инициализирован, если

  • это экземпляр класса/конструкции, в котором конструктор по умолчанию инициализирует все примитивные типы; как экземпляр MyClass;
  • вы используете синтаксис инициализатора массива, e. g. int a[10] = {} (все обнулены) или int a[10] = {1,2}; (все обнулены, кроме первых двух элементов: a[0] == 1 и a[1] == 2)
  • то же самое относится и к неагрегистрационным классам/инструкциям, например MyClass instance = {}; (подробнее об этом можно узнать здесь)
  • это глобальная/экстернная переменная
  • переменная определена static (неважно, внутри функции или в глобальной/пространственной области видимости) - спасибо Джерри

Никогда не доверяйте автоматически инициализируемой переменной простого типа (int, long, ...)! Это может произойти в языках типа C#, но не в C & C++.

68
ответ дан 26 November 2019 в 23:31
поделиться

int не инициализируется нулевым значением. Когда вы говорите int i; , все, что вы делаете, это резервируете место для целого числа. Значение в этом месте не инициализируется. Это делается только тогда, когда вы говорите int i = 0; (или int i = 5; , и в этом случае значение инициализируется равным 5). В любом случае рекомендуется инициализировать переменную некоторым известным значением. В противном случае i содержит любое случайное значение, которое было в этой ячейке памяти, когда для нее было зарезервировано пространство. Вот почему cout выводит случайное значение.

Значения по умолчанию зависят от реализации языка. Некоторые языки инициализируют его некоторым «нормальным» значением (например, 0). Как правило, я всегда инициализирую переменную некоторым разумным значением (если я не знаю, что собираюсь инициализировать ее чем-то другим наверняка , прежде чем использовать). Как я упоминал ранее, неразумно предполагать , что значение будет чем-то разумным. Это может быть или не быть (в зависимости от языка или реализации интерпретатора / компилятора для этого языка).

11
ответ дан 26 November 2019 в 23:31
поделиться

См. Раздел 4.9.5 Инициализация языка программирования C ++.

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

Поскольку вы используете POD (простые старые типы данных), переменная auto не инициализируется никаким значением по умолчанию.

5
ответ дан 26 November 2019 в 23:31
поделиться

На этой записи лучше всего написано: http://www.velocityreviews.com/forums/showpost.php?p=1528247&postcount=10

Нет конструктора "по умолчанию" для неклассовые типы, но по умолчанию (ноль) инициализация. К сожалению, для мозговой совместимости с C, инициализация по умолчанию НЕ выполнена для типов POD обстоятельства:

голый (т.е. объявленный без инициализаторы) переменные локальные к класс или функция.

динамически выделенные экземпляры.

Однако в других местах (в частности. статические переменные) и в случае всё, что угодно, учитывая пустой инициализатор параметры (когда это допустимо), получает инициализация по умолчанию (ноль).

4
ответ дан 26 November 2019 в 23:31
поделиться

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

-121--1732690-

Удалите ветвь, а затем извлеките обе ветви из удаленного репозитория.

git branch -D BUG_37
git pull origin master
git pull origin BUG_37:BUG_37

Если вы не хотите удалять локальную ветвь BUG_37, прежде чем убедиться, что это сработает, переместите удаленную ветвь в другую локальную ветвь:

git pull origin BUG_37:NEW_BUG_37
-121--3147217-

В C++ автоматические переменные не определены, пока им не будет явно присвоено значение. Возможно, вы думаете о C # или других языках .Net, или Java.

3
ответ дан 26 November 2019 в 23:31
поделиться

Для принудительной инициализации POD (которым является int) можно использовать синтаксис инициализатора копирования:

#include <iostream>

int main() {
  int i = int();
  int j;

  std::cout << "i: " << i << std::endl;
  // warning: undefined behavior
  std::cout << "j: " << j << std::endl;
}

Это подпадает под "только платите за то, что используете". Если вы собираетесь впоследствии присваивать значение переменной, или, возможно, не использовать ее вообще, то нет смысла делать работу по ее инициализации. Чтобы это получить, вы должны явно попросить, чтобы эта работа была выполнена.

4
ответ дан 26 November 2019 в 23:31
поделиться

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

0
ответ дан 26 November 2019 в 23:31
поделиться

Локальные переменные не инициализируются, если вы не сделаете это сами. Вы видите мусор, который находился в стеке до вызова вашего метода.

2
ответ дан 26 November 2019 в 23:31
поделиться
Другие вопросы по тегам:

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