关于 while (true), while (cin >> x && x), while (cin >> x, x) 的问题

Question on while (true), while (cin >> x && x), while (cin >> x, x)

我在执行此任务时遇到问题:

your input is a number and the output is from 1 to the input number. If the number is zero, the output will be nothing.

For instance your input is

5
10
3
0

Your output will be

1 2 3 4 5
1 2 3 4 5 6 7 8 9 10
1 2 3

所以,显然有三个答案。

第一个解决方案使用这个:

#include <iostream>
    
using namespace std;
    
int main()
{
    int x;
    while (true)
    {
        cin >> x;
    
        if (!x) break;
    
        for (int i = 1; i <= x; i ++ ) cout << i << ' ';
        cout << endl;
    }
    
    return 0;
}

其他两个解决方案取代了这个:

while (true)
{
    cin >> x;
    
    if (!x) break;

有了这个:

while (cin >> x && x)

或者这个:

while (cin >> x, x)

我理解第一个解决方案,但不理解其他两个。

有人可以帮助我吗?

语句while (cin >> x && x)利用了cin可以转换为bool这一事实。 (bool) cin returns true 如果 cin 没有错误,在大多数情况下这意味着总是 true.

另一个,我不确定,因为我不熟悉那个逗号语法。

对于初学者来说,第一个程序可以调用未定义的行为

int main()
{
    int x;
    while (true)
    {
        cin >> x;

        if (!x) break;
        //...

变量x没有初始化。所以如果输入

cin >> x;

不成功,因为例如用户在 Windows 中按下组合键 Ctrl + z 中断了输入,然后在此 if 语句中

if (!x) break;

将使用导致未定义行为的未初始化变量。

在 while 循环的这种情况下

while (cin >> x, x)

使用了逗号运算符。所以表达式 cin >> x 是否成功被忽略,因为表达式的值被丢弃。

你必须写

while (cin >> x && x != 0 )

注意,变量x是有符号类型int,这意味着用户可以输入负值,循环体将获得控制权。结果会输出多余的换行符

cout << endl;

所以最好将变量x声明为无符号整数类型,例如

unsigned int x;

>> 运算符,按照惯例,当应用于 istream 对象时,应该 return istream 对象本身。所以 cin >> x 的 return 值是 cin 对象本身。当用作布尔值时,如果 input/output.

中没有错误,则流对象 return 为真
while (cin >> x && x)

这表示“当循环成功读取一个值且没有错误时 并且 该值不为零”。

逗号运算符是 C++ 语法中比较晦涩的部分之一。 a , b 计算 a,然后计算 b 和 returns b 的结果,丢弃 a 的结果(这是假设逗号不' 做别的事情;例如,在函数参数列表中,逗号是该语法的一部分,而不是它自己的运算符)。所以 cin >> x, x 说“做 cin 部分,忽略它的 return 值,然后检查 x”。

while (cin >> x, x)

这表示“获取输入并 运行 只要输入不为零”。至关重要的是,这里忽略了输入过程中的错误。


小注:从技术上讲,程序员可以重载逗号运算符来调用任意函数。所以如果一个程序员(我们可能会质疑他的心理健康)写了一个像

这样的函数
void operator,(const istream& in, int x) {
  // Something really stupid ...
}

然后该函数将被 cin >> x, x 调用。但是我见过的每一个 C++ 风格指南都建议不要重载逗号运算符,所以这充其量是病态的。

第一个while可以读作:

  • 如果std::cincin >> xx != 0之后没有错误,则执行while块。
  • 否则,退出该块。

查看流的 operator bool,了解如何在逻辑表达式中使用 cin >> x

第二个while可以读作:

  • cin >> x.
  • 然后,如果x != 0,执行while块。
  • 否则,退出该块。

查看 comma operator 了解表达式中 , 的用法。

您应该指定可以接收哪些输入的规则。例如,如果您只需要正整数,您可以指定 if x <= 0; return error