c++ - 这真的能确保数字在 1-9 之间吗?

标签 c++

int position = 0;

void set_position() {

  std::cout << "Player " << player << "'s Turn (Enter 1-9): ";

  while (!(std::cin >> position)) {

    std::cout << "Player " << player << ", please enter a valid number between 1 and 9: ";
    std::cin.clear();
    std::cin.ignore();

  }

  std::cout << "\n";

  while (board[position-1] != " ") {

    std::cout << "Oops, there's already something in that position!\n\n";

    std::cout << "Player " << player << "'s Turn (Enter 1-9): ";
    std::cin >> position;

    std::cout << "\n";
  }

}

这是 Codecademy 中井字棋挑战的解决方案,我想了解函数 while (!std::cin >>position)) 是否实际检查它是否为 1 到9. Position 只是一个 int,声明为 intposition = 0;。它实际上是如何检查它是否是 1 到 9 的?或者它只是检查它是否是一个整数?到目前为止,Codecademy 的 C++ 类(class)似乎相当糟糕,并且没有讲太多内容。

最佳答案

太长时间没有阅读(TLDR)

该代码仅过滤掉非数字。

说明:

为了帮助您理解,让我们看看里面实际发生了什么

while(!(std::cin >> position))

在所有谎言的内部std::cin >> position>>是“提取运算符”,因此我们将从 std::cin 中提取一些内容(标准输入)。使用>>接线员实际上只是转身调用 operator>>()在给定的对象上。本例中的给定对象是 std::istream。这是operator>>()调用签名如下所示:

istream& operator>> (int& val)

它返回 istream (本身),并引用 int , position在你的情况下。

所以如果我们评估 std::cin >> position在心理上(或者在调试器中,这要好得多:零猜测),我们会看到我们已经返回了 istream (几乎可以肯定函数末尾是 return *this;)。

现在让我们替换 std::cin >> position有效返回值std::cin看看代码是什么样的。

while(!(std::cin))

好的,所以我们需要应用 !运算符到 istream命名cin 。 “等等什么?!”你哭了...任何类/结构都可以定义各种不同的运算符,例如 <<, >>, =, ==, >, <, !, *, ->...他们有很多。相关的是!运算符,具有以下函数签名和文档:

bool operator!() const

Returns true if either failbit or badbit is set, and false otherwise. This is equivalent to calling member fail.

顺便说一句,const最后的意思是“我们 promise 不会更改运行该函数的对象”。这允许编译器进行各种优化,知道对象的状态不会改变。它还让我们的程序员同事知道函数内部正在发生(以及)发生什么类型的事情。

当您在 operator>>(int&) 中输入非数字时,我们预计这会返回 true(设置了失败或错误) ,我们是对的。为遵循“最小惊喜原则”的库设计者干杯。

operator!()的返回值然后被传递到 while 循环中。因此,如果有人输入字母或标点符号或您拥有的其他内容,他们会看到错误消息并必须重新输入。

结论:

这对于过滤 1-9 之外的数字没有任何作用,它只是过滤掉非数字。您需要为此编写新代码,例如@Eljay 评论中的建议。

关于c++ - 这真的能确保数字在 1-9 之间吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61728599/

相关文章:

c++ - 如何以素数为模计算非常大的二项式系数?

c++ - 使用按位运算符的 PE 文件格式指针

c++ - 我应该传递什么来抛出?

c++ - 尝试制作我自己的字符串类

c++ - 编写 STL 兼容的迭代器

c++ - 在用户模式线程中旋转 volatile 变量是否安全?

C++ 将 std::vector<Derived>* 转换为 std::vector<Base> ...?

在 OSX Sierra 上找不到 C++ header

c++ - 在非托管程序中托管 CLR 时从内存加载程序集

c++ - 在 C++ 中扩展 C 结构