Инициализация переменной в C ++ - PullRequest
39 голосов
/ 07 февраля 2010

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

int main () 
{   
    int a[10];
    int i;
    cout << i << endl;
    for(int i = 0; i < 10; i++)
        cout << a[i] << " ";
    return 0;
}
  • Какие правила, если таковые имеются, применяются к инициализации?
  • В частности, при каких условиях переменные инициализируются автоматически?

Ответы [ 11 ]

66 голосов
/ 07 февраля 2010

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

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

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

11 голосов
/ 07 февраля 2010

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

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

5 голосов
/ 07 февраля 2010

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

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

Поскольку вы используете POD (Plain Old Datatypes), для автоматической переменной не задано значение по умолчанию.

4 голосов
/ 08 февраля 2010

Чтобы принудительно инициализировать 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 голосов
/ 07 февраля 2010

Это сообщение лучше всего говорит: http://www.velocityreviews.com/forums/showpost.php?p=1528247&postcount=10

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

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

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

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

3 голосов
/ 26 октября 2012

Различные операционные системы (т.е. OS X и Ubuntu Linux) будут по-разному реагировать на неинициализированные и инициализированные переменные в C ++.По моему опыту, версия gcc для OS X скомпилирует и распечатает 2 для обеих версий кода ниже.Где, как будто я работаю на машине с Ubuntu Linux, первый блок кода распечатает все, что было в ячейке памяти, на которую ссылаются переменные (+ 2 после цикла).

    int c;

    for( int i = 0; i < 3; i++ )
    {
        c++;
    }

    cout << c << endl; 

Где как,все они дадут вам одинаковые результаты для:

    int c = 0;

    for( int i = 0; i < 3; i++ )
    {
        c++;
    }

    cout << c << endl; 
3 голосов
/ 07 февраля 2010

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

2 голосов
/ 18 марта 2011

Если для объекта не указан инициализатор, объект инициализируется по умолчанию; если инициализация не выполняется, объект с автоматическим или динамическим сроком хранения имеет неопределенное значение.

Пар. 8.5, раздел 11 последней версии C ++ 0x N3092.pdf,

http://www.open -std.org / ОТК1 / SC22 / wg21 / документы / документы / 2010 /

2 голосов
/ 07 февраля 2010

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

0 голосов
/ 15 июля 2017

Здесь int i; - это автоматическая переменная, которую нужно инициализировать вручную. Переменная auto не инициализируется автоматически в c и c ++.

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

объявить i как статическую переменную.

static int i; // ноль присваивается i компилятором.

объявить i как глобальную переменную [вне main ()]. ​​

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