为什么变量初始化为0?

Erg*_*oxy 21 c++ variables

我刚开始从电子书中学习C++.
我的代码没有任何错误,但我确实有一个问题.
本书使用以下代码总结两个数字:

#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;
}
Run Code Online (Sandbox Code Playgroud)

因此int v1 = 0,v2 = 0;用于变量.为什么他们被初始化为0?

Kon*_*lph 22

这是货物崇拜节目.它不是有害的,但它在这里没有任何实际好处,而且可能只是因为作者想要简化教学目的的概念,或者因为他误解了某些东西.

这就是原因.

通常,所有变量应在声明后直接初始化.这可确保变量永远不会处于不确定状态.这使得控制流程更简单,代码更容易推理,从而防止错误.

但是,这只有在我们能够使用有意义的值初始化变量时才有意义 - 即使用稍后要表示的值.在你的代码中,情况并非如此 - 相反,变量后来通过输入流来分配它们的值(遗憾的是,C++不支持使用从输入读取的值初始化变量的简洁,规范的方法).

正如@jrok所说,初始化表面上可以防止无效输入和代码中的后续错误.我说表面上是因为那不是真的:我们用 - 0- 初始化变量的值在程序的上下文中也是无效的,所以我们实际上没有获得任何东西.

Jack Aidley提出这个代码的真正原因是防止编译器警告.但是由于上面提到的原因,没有编译器应该在这里警告.事实上,即使编译时启用了大量警告,GCC 也不会发出警告.也许其他编译器会这样做,但我会考虑这个警告噪音.

  • @Thomas实际上我更多地考虑`auto i = read <int>(cin);`这很容易作为库解决方案.`read`将返回一个类似于'boost :: optional`的值,或者函数可能会在失败时抛出异常(但第一个变体有许多优点).事实上,每当我的代码严重依赖IO时,我就会使用这些函数. (3认同)

jro*_*rok 15

int v1 = 0;
Run Code Online (Sandbox Code Playgroud)

这叫做初始化,这是一个很好的习惯.如果省略内置类型的初始值设定项,则调用其值是不确定的,读取这样的值是非法的.

我们假设你这样做:

int v1;
std::cin >> v1;
std::cout << v1;
Run Code Online (Sandbox Code Playgroud)

第二行中的输入操作可能会失败,例如,如果您输入字母而不是数字,v1则保持不变.没有检查输入是否成功,如果v1仍未发生未初始化,爆炸!您已经调用了未定义的行为,并且您仍然受编译器的支配,可以执行任何想要的操作.

在你发布的代码中,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
}
Run Code Online (Sandbox Code Playgroud)

流可以隐式转换为bool,如果没有设置错误标志,它们会评估truefalse否则.

完成上述检查后,几乎不需要初始化,因为我们永远不会触摸v1,v2如果输入失败.

  • 没有downvote但我不同意 - 初始化在这里没用,不要这样做.你让它听起来像防御性编码,但实际上它只是隐藏了一个错误,即无法检查输入是否成功.仅初始化具有有意义值的变量,而不是伪造的占位符. (11认同)
  • 您的示例与初始化无关.如果读取操作失败,则无论是否初始化,"v1"的值都是不确定的. (5认同)

Pet*_*ker 13

这是一种常见的做法,但在这个例子中,这是一个没有充分考虑错误处理的解决方法.如果不初始化它们,则可以获得无效值的合理化仅在您不费力检查输入是否成功时才有意义.代码不会检查输入是否成功,因此它存在致命缺陷.没有多少其他不需要的初始化可以解决这个问题.

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";
Run Code Online (Sandbox Code Playgroud)