Подтвердить что ты не робот

Инициализация переменных в С++

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

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

Ответ 1

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

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

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

Ответ 2

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

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

Ответ 3

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

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

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

Ответ 4

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

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

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

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

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

Ответ 5

Чтобы принудительно инициализировать 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;
}

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

Ответ 6

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

Ответ 7

Различные операционные системы (то есть OS X против Ubuntu Linux) будут реагировать по-разному на неинициализированные или инициализированные переменные в С++. По моему опыту, версия gcc для OS X gcc будет компилировать и распечатывать 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; 

Ответ 8

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

Ответ 9

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

Пар. 8.5, раздел 11 недавнего проекта С++ 0x N3092.pdf,

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/

Ответ 10

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

Ответ 11

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

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

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

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

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