深入理解 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 ...
随机推荐
- bootstrap导航栏.nav与.navbar区别
刚刚看了bootstrap的导航栏,发现有点弄混了,现在来整理一下: 一.简单的ul,li组成的导航: <ul class="nav nav-pills justify-content ...
- Weblogic之简介
一.简介(来自百度百科) WebLogic是美国Oracle公司出品的一个application server,确切的说是一个基于JAVAEE架构的中间件,WebLogic是用于开发.集成.部署和 ...
- sqlmap命令
-u #注入点 -f #指纹判别数据库类型 -b #获取数据库版本信息 -p #指定可测试的参数(?page=1&id=2 -p "page,id") -D "& ...
- Spring4 AOP详解
Spring4 AOP详解 第一章Spring 快速入门并没有对Spring4 的 AOP 做太多的描述,是因为AOP切面编程概念不好理解.所以这章主要从三个方面详解AOP:AOP简介(了解),基于注 ...
- gulp基础操作实践
按照gulp中文文档对gulp基础操作的一些实践练习,记录以防忘掉. 一,选择并输出文件:gulp.src(globs[,options]) eg:gulp.src('src/less/index.l ...
- 《java.util.concurrent 包源码阅读》04 ConcurrentMap
Java集合框架中的Map类型的数据结构是非线程安全,在多线程环境中使用时需要手动进行线程同步.因此在java.util.concurrent包中提供了一个线程安全版本的Map类型数据结构:Concu ...
- 简单的OC程序
知识点 1.#import的用途: 1> 跟#include一样,拷贝文件的内容 2> 可以自动防止文件的内容被重复拷贝 2.#import <Foundation/NSObjCRu ...
- scrapy初试水 day03(递归调用)
import scrapyfrom scrapy.http import Requestfrom scrapy.spider import Rulefrom scrapy.linkextractors ...
- 51Nod 1084 矩阵取数问题 V2 双线程DP 滚动数组优化
基准时间限制:2 秒 空间限制:131072 KB 一个M*N矩阵中有不同的正整数,经过这个格子,就能获得相应价值的奖励,先从左上走到右下,再从右下走到左上.第1遍时只能向下和向右走,第2遍时只能向 ...
- 51Nod1136--欧拉函数
1136 欧拉函数 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 对正整数n,欧拉函数是少于或等于n的数中与n互质的数的数目.此函数以其首名研究者欧拉命 ...