是否有理由使用零定位化,而不是在要在使用该值之前进行更新时根本不定义变量?

发布于 2025-01-31 06:25:39 字数 707 浏览 2 评论 0原文

我遇到了一个代码示例 他们在哪里零化变量,然后用std :: cin进行定义:

#include <iostream>  // for std::cout and std::cin

int main()
{
    std::cout << "Enter a number: "; // ask user for a number

    int x{ }; // define variable x to hold user input (and zero-initialize it)
    std::cin >> x; // get number from keyboard and store it in variable x

    std::cout << "You entered " << x << '\n';
    return 0;
}

是否有任何理由在第7行上您不会不只是初始化x?似乎零启动变量是浪费时间,因为它在下一行中分配了新值。

I came across a code example learncpp.com where they zero-initialized a variable, then defined it with std::cin:

#include <iostream>  // for std::cout and std::cin

int main()
{
    std::cout << "Enter a number: "; // ask user for a number

    int x{ }; // define variable x to hold user input (and zero-initialize it)
    std::cin >> x; // get number from keyboard and store it in variable x

    std::cout << "You entered " << x << '\n';
    return 0;
}

Is there any reason that on line 7 you wouldn't just not initialize x? It seems zero-initializing the variable is a waste of time because it's assigned a new value on the next line.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

欢烬 2025-02-07 06:25:39

有什么原因是在第7行上您不会不只是初始化x?

通常,建议应始终初始化内置类型内置的本地/块范围。这是为了防止内置不确定价值的类型内置的潜在用途,并将导致不确定的行为

在您的特定示例中,尽管在下一行中,我们有std :: cin&gt;&gt; X;因此可以安全地省略上一行中的零初始化。

还请注意,在您的示例中,如果读取输入因某种原因失败,则在C ++ 11之前,X仍然具有不确定的值,但从C ++ 11(&amp; onwards)x 将根据以下引用的语句具有不确定的价值。

来自 basic_istream的文档

如果提取失败(例如,如果在预期数字的位置输入字母),则将零写入值,而failbit设置。对于已签名的整数,如果提取导致值太大或太小而无法符合价值,则std :: numeric_limits&lt; t&gt; :: max()或 or std :: nemeric_limert&lt; t&gt; t&gt; :: min()分别编写,并设置了FailBit标志。对于未签名的整数,如果提取导致值太大或太小而无法符合价值,则编写std :: numeric_limits&lt; t&gt; :: max()是编写的,并且fafs> failbit 设置标志。

似乎零启动变量是浪费时间,因为它是在下一行上重新定义的。

就像我说的那样,在您的示例中,假设您使用的是C ++ 11(''更高),则可以安全地删除零定位化。


然后用std :: cin

定义它

std :: cin不使用“定义” IT(x)。定义仅在您写作时仅发生一次:

int x{ }; //this is a definition

即使您离开零初始化,也将是一个定义:

int x;  //this is also a definition but x is uninitialized here

Is there any reason that on line 7 you wouldn't just not initialize x?

In general, it is advised that local/block scope built in types should always be initialized. This is to prevent potential uses of uninitialized built in types which have indeterminate value and will lead to undefined behavior.

In your particular example though since in the immediate next line we have std::cin >> x; so it is safe to omit the zero initialization in the previous line.

Note also that in your example if reading input failed for some reason then prior to C++11, x still has indeterminate value but from C++11(&onwards) x will no longer has indeterminate value according to the below quoted statement.

From basic_istream's documentation:

If extraction fails (e.g. if a letter was entered where a digit is expected), zero is written to value and failbit is set. For signed integers, if extraction results in the value too large or too small to fit in value, std::numeric_limits<T>::max() or std::numeric_limits<T>::min() (respectively) is written and failbit flag is set. For unsigned integers, if extraction results in the value too large or too small to fit in value, std::numeric_limits<T>::max() is written and failbit flag is set.

It seems zero-initializing the variable is a waste of time because it's redefined on the next line.

As i said, in your example and assuming you're using C++11(& higher), you can safely leave off the zero-initialization.


then defined it with std::cin

No the use of std::cin does not "define" it(x). Definition happened only once when you wrote:

int x{ }; //this is a definition

Even if you leave the zero initialization, then also it will be a definition:

int x;  //this is also a definition but x is uninitialized here
高冷爸爸 2025-02-07 06:25:39

您遇到的问题是,为了使用&gt;&gt; std :: cin的操作员,您必须事先声明变量,这是,好,不希望。这也会导致您的问题是否初始化变量。

取而代之的是,您可以做这样的事情:

#include <iostream>
#include <iterator>

int main()
{
    std::cout << "Enter a number: ";
    auto const i = *std::istream_iterator<int>(std::cin);
    std::cout << "You entered " << x << '\n';
}

...虽然这也是有问题的,因为您处于档案的结尾,然后行为是未定义的

现在,您可能会问:“为什么这个人与我谈论采取共同方式的替代方案,然后告诉我替代方案也不够好?”

我这样做的目的是向您介绍“ C ++生活”的不舒服事实,这是:我们经常被标准库的设计决策所困扰,这些决策不是最佳的。有时,确实没有更好的选择。有时有,但没有采用 - 而且由于C ++不容易更改标准图书馆类的设计,因此我们可能会被语言中的一些“疣”。另请参阅我打开的相关问题中的讨论:

The problem you're encountering is, that in order to use the >> operator of std::cin, you have to have your variable declared beforehand, which is, well, undesirable. It also leads to your question of whether or not to initialize the variable.

Instead, you could do something like this:

#include <iostream>
#include <iterator>

int main()
{
    std::cout << "Enter a number: ";
    auto const i = *std::istream_iterator<int>(std::cin);
    std::cout << "You entered " << x << '\n';
}

... although that's also problematic, since you're at the end-of-file, then the behavior is undefined.

Now, you might be asking "why is this guys talking to me about alternatives to the common way of doing things, then telling me that the alternative isn't good enough either?"

The point of my doing this is to introduce you to an uncomfortable fact of "C++ life", which is: We are often stuck with design decisions of the standard library which are not optimal. Sometimes, there's really no better alternative; and sometimes there is, but it wasn't adopted - and since C++ does not easily change designs of standard library classes, we may be stuck with some "warts" in the language. See also the discussion in the related question I've opened:

Why do C++ istreams only allow formatted-reading into an existing variable?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文