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

Почему переменные инициализируются до 0?

Я только начал изучать С++ из книги.
У меня нет ошибок в моем коде, но у меня есть вопрос.
В книге используется следующий код для суммирования двух чисел:

#include <iostream>
int main()
{
    std::cout << "Enter two numbers:" << std::endl;
    int v1 = 0, v2 = 0;
    std::cin >> v1 >> v2;
    std::cout << "The sum of " << v1 << " and " << v2
        << " is " << v1 + v2 << std::endl;
    return 0;
}

So int v1 = 0,v2 = 0; используется для переменных. Почему они инициализируются до 0?

4b9b3361

Ответ 1

int v1 = 0;

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

Предположим, вы это сделаете:

int v1;
std::cin >> v1;
std::cout << v1;

Операция ввода во второй строке может завершиться неудачей, например, если вы вводите букву вместо числа, а v1 останется нетронутой. Невозможно проверить, удалось ли вход, и если v1 все еще происходит с неинициализированным, bang! Вы вызывают поведение undefined, и вы остаетесь во власти компилятора, чтобы сделать все, что захотите.

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

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

Самый простой способ сделать это - использовать входное выражение в булевом контексте, внутри if условие:

if (std::cin >> v1 >> v2) {
    // good, use v1 and v2
} else {
    // bad input, we can't
    // rely on v1 and v2 to
    // have meaninful value here
}

Потоки неявно конвертируются в bool, и если флаги ошибок не установлены, они оцениваются в true и false в противном случае.

Проделав вышеуказанную проверку, мало что нужно для инициализации, поскольку мы никогда не коснемся v1 и v2, если вход не удался.

Ответ 2

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

Вот почему.

Обычно все переменные должны быть непосредственно инициализированы после объявления. Это гарантирует, что переменная никогда не находится в неопределенном состоянии. Это упрощает управление потоком, код легче рассуждать и, как следствие, предотвращает ошибки.

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

Как сказал @jrok, инициализация якобы защищает от недопустимых входов и последующих ошибок в коде. Я говорю якобы, потому что это на самом деле не верно: значение, которое мы инициализировали переменными с - 0, также недопустимо в контексте программы, поэтому мы ничего не получили.

Jack Aidley предлагает, что настоящая причина этого кода - предотвратить предупреждение компилятора. Но компилятор здесь не должен предупреждать по причине, изложенной выше. И на самом деле GCC не предупреждает, даже если скомпилировано множество предупреждений. Возможно, другие компиляторы делают, но я бы рассмотрел этот предупреждающий шум.

Ответ 3

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

std::cin >> v1 >> v2;
if (std::cin)
    std::cout << "The sum of " << v1 << " and " << v2
        << " is " << v1 + v2 << std::endl;
else
    std::cout << "Bogus input\n";

Ответ 4

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

Но в вашем примере это не важно, потому что вы устанавливаете значение с чтением cin.

Ответ 5

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

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

Ответ 6

Это часть общей практики.

Лучше инициализировать значение переменной, чтобы дать ей ощущение полноты.