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

Значение переменной по умолчанию

Если я не присваиваю значение переменной, когда я ее объявляю, по умолчанию она равна нулю или только что было ранее в памяти?

например.

float x;
4b9b3361

Ответ 1

Объявленная переменная может быть Zero Initialized, Инициализировано значение или Инициализировано по умолчанию.

С++ 03 Standard 8.5/5 точно определяет каждый из них:

В zero-initialize объект типа T означает:

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

В default-initialize объект типа T означает:
- если T - тип класса не-POD (раздел 9), вызывается конструктор по умолчанию для T (и инициализация плохо сформирована, если T не имеет доступного конструктора по умолчанию); - если T - тип массива, каждый элемент инициализируется по умолчанию;
- в противном случае объект инициализируется нулем.

В value-initialize объект типа T означает:
- если T - тип класса (раздел 9) с объявленным пользователем конструктором (12.1), то по умолчанию конструктор для T называется (и инициализация плохо сформирована, если T не имеет доступного конструктор по умолчанию); - если T - тип неединичного класса без конструктора, объявленного пользователем, то каждый нестатический элемент данных и компонент базового класса T инициализируются значением;
- если T - тип массива, то каждый элемент инициализируется значением; - в противном случае объект инициализируется нулем

Например:

#include<iostream>
using namespace std;

static int a; //Zero Initialized
int b; //Zero Initialized

int main()
{
    int i;  //Undefined Behavior, Might be Initialized to anything
    static int j; //Zero Initialized

    cout<<"\nLocal Uninitialized int variable [i]"<<i<<"\n";

    cout<<"\nLocal Uninitialized Static int variable [j]"<<j<<"\n";

    cout<<"\nGlobal Uninitialized Static int variable [a]"<<a<<"\n";

    cout<<"\nGlobal Uninitialized int variable [b]"<<b<<"\n";

    return 0;
}

Вы заметите, что результаты для переменной i будут разными для разных компиляторов. Такие локальные неинициализированные переменные ДОЛЖНЫ НИКОГДА. Фактически, если вы включаете строгие предупреждения компилятора, компилятор должен сообщить об ошибке. Здесь, как кодовое сообщение сообщает об ошибке.

cc1plus: warnings being treated as errors
In function 'int main()':
Line 11: warning: 'i' is used uninitialized in this function

Edit: Как справедливо указал @Kirill V. Ladvinsky в комментариях, ДОЛЖНО НИКОГДА - довольно сильное слово, и может быть совершенно допустимый код, который может использовать неинициализированные переменные, поскольку он указывает в своем комментарии. Поэтому, наверное, я должен сказать:
Вы никогда не должны использовать неинициализированные переменные, если не знаете точно, что делаете.

Ответ 2

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

Ответ 3

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

Ответ 4

Это зависит от того, где вы его объявляете. Переменные в глобальной области инициализируются 0, а переменные стека - undefined.

Ответ 5

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

UPDATE: согласно комментариям - глобальные переменные будут инициализированы нулем. Локальные переменные будут любыми.

Чтобы ответить на второй вопрос:

Спасибо за то, что после этого есть ярлык для назначения нуля всем следующим: float x1, x2, x3, x4, x5, y1, y2, y3, y4, y5

Вы могли бы сделать

float x[5] = {0,0,0,0,0}; float y[5] = {0,0,0,0,0};

и используйте x[0] вместо x1.

Ответ 6

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

Ответ 7

Используя значение любой переменной до инициализации (обратите внимание, что объекты статической памяти всегда инициализируются, поэтому это относится только к длительности автоматического хранения) приводит к undefined поведению. Это сильно отличается от того, что 0 является исходным значением или содержит случайное значение. UB означает, что возможно что-либо. В реализациях с битами ловушки может произойти сбой вашей программы или генерация сигнала. Также возможно, что множественные считывания приводят к различным непредсказуемым значениям, среди любого другого воображаемого (или невообразимого) поведения. Просто не используйте значение неинициализированных переменных.

Примечание: На основе комментариев было отредактировано следующее:

Обратите внимание, что такой код недопустим, если вы не уверены, что тип foo_t не имеет битов дополнений:

foo_t x;
int i;
for (i=0; i<N; i++) x = (x<<1) | get_bit();

Несмотря на то, что намерение заключается в том, что "случайное значение" изначально в x отбрасывается до окончания цикла, программа может вызывать UB, как только он обращается к x, чтобы выполнить операцию x<<1 на первой итерации, и, следовательно, весь вывод программы недействителен.

Ответ 8

С++ не создает переменные. Значение x - это то, что было в памяти в то время. Никогда не предполагайте ничего о его первоначальном значении.