深入理解 while(cin >> x >> y)
初步分析
在C++中实现连续输入时,我们会用到 while(cin >> x >> y) ,但是它的条件判断的原理可不那么好想,这里我分享一下我对于它的见解。
首先来看 cin >> x >> y,它的返回值是什么?首先要明确的是 cin 是一个 istream 对象,一个对象并没有返回值这个概念,那可以产生返回值的东西就只有" >> "运算符符了。在《C++ primer(第五版)》中我们知道,"">>"运算符左边是一个 istream 对象,右边是需要被输入的对象,它返回其左侧运算对象作为计算结果。也就是说, 它每次进行一次运算后返回的都是 istream 对象,在这里就是标准输入 cin。
">>"运算符背后的机制是引用与运算元重载,这种选项可以更方便地返回左值(左值就是可以被取地址运算符 & 操作的变量),而 istream::opreator>>() 就需要返回左值,才能做到 (cin >> x) >> y。
这就是为什么 std::cin >> x >> y; 可以等价于 (std::cin >> x) >> y; 和 std::cin >> x; std::cin >> y; 的原因。
知道了返回值是什么后,问题还是没有解决,因为我们不知道如何判断一个对象的值是 TRUE 还是 FALSE ,看来得深究一下 cin 对象了。
cin 对象的深入理解
通过查阅资料,我们知道 cin 是行缓冲。对于行缓冲的描述,man手册里有如下的一句话可以很好的说明什么是行缓冲:

大概意思是:cin 是行缓冲,你从键盘上输入一串字符,这一串字符首先会被缓冲区保存下来。每当你按下回车键的时候,cin 就会检测输入缓冲区是否有可读的数据。在这里,cin 会检查键盘输入是否有流结束标志 CTRL + X (我用的是 Linux,Windows是 CTRL + Z) 和 CTRL + D(EOF)。在这里我翻阅了网上资料,发现检查的方法一共有两种,一种是阻塞式检查,一种是非阻塞式检查。
阻塞式检查是这样:只有在你按下回车后才能检查之前是否输入了 CTRL + X。
非阻塞式检查是这样:只要你按了 CTRL + D,就立即响应。如果你按下 CTRL + D 之前还有字符,此时 CTRL + D 相当于是回车的作用,会把你之前从键盘输入的字符输入缓冲区供读取使用。
我们拿一个程序验证一下所讨论的两种检查方式:
//This program's name is 1.cpp
#include<iostream>
int main(void)
{
int i;
cout << (cin >> i) << endl;
;
}
Input:
1、从键盘输入:“12345" + CTRL + D;
2、从键盘输入:CTRL + D;
3、从键盘输入:"12345" + CTRL + X;
4、从键盘输入:CTRL + X。
Output:

结果:
1、立马响应,同时将12345读入输入缓冲区并输出括号里的值;
2、立马响应,输出括号里值,此时 cin 对象值为0
3、先不响应,再输入回车后立马响应,同时读入”12345“
4、先不响应,再输入回车后立马响应,此时 cin 对象值为0
总结
标题中的两个条件判断都可以这么想:由于 cin 是行缓冲且存在两种阻塞检查机制,当你按下 CTRL + D 或者 按下 CTRL + X + 回车,cin 接收到流结束标志,使得 cin 的值为0,导致条件判断为 FALSE。这是我个人的分析,可能有部分知识不严谨,欢迎指正。
深入理解 while(cin >> x >> y)的更多相关文章
- <python 深入理解>变量交换x,y=y,x实现机制--元组
python中有一种赋值机制即多元赋值,采用这种方式赋值时,等号两边的对象都是元组并且元组的小括号是可选的.通常形式为 x, y, z = 1, 2, 'a string' 等同于 (x, y, z) ...
- C++IO关于cin>>和getline的理解
这个问题困扰了我有一段时间了,趁着十一放假有时间,仔细研究了一下 首先来看一下输入输出运算符cin>>的构成:cin和>> cin>>是由两部分构成的,cin和&g ...
- Deep learning:五十(Deconvolution Network简单理解)
深度网络结构是由多个单层网络叠加而成的,而常见的单层网络按照编码解码情况可以分为下面3类: 既有encoder部分也有decoder部分:比如常见的RBM系列(由RBM可构成的DBM, DBN等),a ...
- Effective Java通俗理解(持续更新)
这篇博客是Java经典书籍<Effective Java(第二版)>的读书笔记,此书共有78条关于编写高质量Java代码的建议,我会试着逐一对其进行更为通俗易懂地讲解,故此篇博客的更新大约 ...
- 对于BFS的理解和部分例题(
(图文无关 雾 搜索是一个NOIP当中经常出现的考点,其实搜索换个方式来想也无非就是让电脑来帮你试,最后得到一个结果,当然这么口胡谁都会,那么我们就来看看搜索当中的一个大部分: BFS(广度优先 ...
- Effective Java通俗理解(上)
这篇博客是Java经典书籍<Effective Java(第二版)>的读书笔记,此书共有78条关于编写高质量Java代码的建议,我会试着逐一对其进行更为通俗易懂地讲解,故此篇博客的更新大约 ...
- 关于scanf与cin哪个快的问题
一开始入c++的时候成天跑cin,cout 直到有一天用cin,cout超时 才知道scanf比cin快的多 但是后来又听说加了ios::sync_with_stdio(false);的cin跟飞一样 ...
- dijkstra算法理解+模板
2017-09-17 21:10:45 writer:pprp 看了看dijkstra算法,用自己语言总结一下主要过程吧, 首先,明确这个算法用处是在于计算单源最短路径问题并且边权非负,给出一个起点可 ...
- hdu 1556 涂气球 线段树(区间更新~对区间[x,y]更新,求任意节点被更新的次数)
Color the ball Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
随机推荐
- Office隐藏17年的漏洞CVE_2017_11882测试记录
Office隐藏17年的漏洞CVE_2017_11882测试记录 创建时间: 2017/11/25 0:18 作者: CN_Simo 标签: Office漏洞 参考文章1:https://www.cn ...
- MeshRenderer组件及相关API
MeshRenderer:网格过滤器,用于"渲染"显示模型. Cast Shodows:是否投射阴影.(on:开.off:关) Receive Shodows:是否接收阴影. Ma ...
- C#设计模式之十七观察者模式(Observer Pattern)【行为型】
一.引言 今天是2017年11月份的最后一天,也就是2017年11月30日,利用今天再写一个模式,争取下个月(也就是12月份)把所有的模式写完,2018年,新的一年写一些新的东西.今天我们开始讲& ...
- 大数据查询——HBase读写设计与实践
导语:本文介绍的项目主要解决 check 和 opinion2 张历史数据表(历史数据是指当业务发生过程中的完整中间流程和结果数据)的在线查询.原实现基于 Oracle 提供存储查询服务,随着数据量的 ...
- 3721:和数-poj
总时间限制: 1000ms 内存限制: 65536kB 描述 给定一个正整数序列,判断其中有多少个数,等于数列中其他两个数的和. 比如,对于数列1 2 3 4, 这个问题的答案就是2, 因为3 = ...
- Service使用详解
Service是Android系统中的四大组件之一,主要有两个应用场景:后台运行和跨进程访问.Service可以在后台执行长时间运行操作而不提供用户界面,除非系统必须回收内存资源,否则系统不会停止或销 ...
- <meta http-equiv="X-UA-Compatible" content="IE=edge">的作用
X-UA-Compatible是针对ie8新加的一个设置,对于ie8之外的浏览器是不识别的. X-UA-Compatible 是针对 IE8 版本的一个特殊文件头标记,用于为 IE8 指定不同的页面渲 ...
- [转] linux系统中如何进入退出vim编辑器,方法及区别
原文链接:http://www.cnblogs.com/crazylqy/p/5649860.html 在linux家族中,vim编辑器是系统自带的文本编辑器,其功能强大自不必说了. 偶有小白,刚接触 ...
- gcc & gdb & make 定义与区别
GCC 通常所说的GCC是GUN Compiler Collection的简称,除了编译程序之外,它还含其他相关工具,所以它能把易于人类使用的高级语言编写的源代码构建成计算机能够直接执行的二进制代码. ...
- [PHP基础]有关isset empty 函数的面试题
用isset()和empty()判断下面的变量. $str = ''; $int = 0 ; $arr = array(); isset($str) 返回的是 true 还是 false empty( ...