21

我刚从一本电子书开始学习 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;
}

所以int v1 = 0,v2 = 0;用于变量。为什么将它们初始化为0?

4

6 回答 6

22

这是货物崇拜编程。它不是有害的,但在这里没有真正的好处,并且可能只是因为作者想简化概念以用于教学目的,或者因为他误解了某些东西。

这就是为什么。

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

但这只有在我们可以用有意义的值初始化变量时才有意义——即使用它稍后要表示的值。在您的代码中,情况并非如此——相反,变量稍后通过输入流获得它们的值(不幸的是,C++ 不支持使用从输入读取的值初始化变量的简洁、规范的方式)。

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

Jack Aidley 提供了这段代码的真正原因是为了防止编译器警告。但由于上述原因,编译器不应在此处发出警告。事实上,GCC不会发出警告,即使在编译时启用了很多警告。也许其他编译器会这样做,但我会考虑这种警告噪音。

于 2013-08-03T13:40:52.253 回答
15
int v1 = 0;

这称为初始化,这是一个好习惯。如果你省略了内置类型的初始化器,它的值被称为不确定,读取这样的值是非法的。

假设您这样做:

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

第二行中的输入操作可能会失败,例如,如果您输入字母而不是数字,并且v1将保持不变。没有检查输入是否成功,如果v1仍然发生未初始化,砰!你已经调用了未定义的行为,你只能任由编译器来做它想做的任何事情。

在您发布v1v2已初始化的代码中,即使输入失败,您至少会得到一些具有明确行为的结果。

也就是说,不检查输入是否成功是一个逻辑错误。毕竟,这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,如果没有设置错误标志,则它们评估为truefalse否则。

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

于 2013-08-03T08:46:53.720 回答
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";
于 2013-08-03T10:59:46.490 回答
1

在定义变量时为变量设置一个值是一种常见的做法。有时,当您尝试使用未使用值初始化的变量时,您会遇到严重错误。

但在您的示例中,这并不重要,因为您使用 cin read 设置了一个值。

于 2013-08-03T08:44:29.160 回答
0

虽然其他答案是正确的,但我不认为它们可能是这些变量被初始化为零的实际原因。

相反,我强烈怀疑原因是这样的:如果不是,大多数编译器会发出有关使用未初始化变量的警告。我相信这里的初始化主要或纯粹是为了抑制发出警告。

于 2013-08-03T11:18:50.273 回答
-1

这是常见做法的一部分。

最好将一个值初始化为一个变量,以使其具有完整感。

于 2013-08-03T13:21:48.480 回答