[cpp] I/O操作符号返回数值问题

简介:

原文地址:http://www.cnblogs.com/alex-tech/archive/2012/03/27/2420197.html

I/O操作符号(<<和>>)返回数值


最近博问里有几个问题都牵涉到这一点了,简单做笔记说明一下。

首先cin是一个对象,不会"返回"值,>>和<<才是方法,具有返回值。>>和<<操作符的运算顺序是由左向右边,所以下面的两种语句描述其实是一致的:

cin>>a>>b>>c;
(((cin>>a)>>b)>>c);

操作cin>>a的意义: 调用istream 的operator>>方法读取数据并存入变量a中。那么>>或者<<的返回值是什么呢?这里说的返回值并不是指读入变量中的值,而是返回赋给左值的数据,在这里, >>返回的是cin,追踪源码可以发现这一点:

istream& operator>> (istream& is, char& ch );
istream& operator>> (istream& is, signed char& ch );
istream& operator>> (istream& is, unsigned char& ch );
istream& operator>> (istream& is, char* str );
istream& operator>> (istream& is, signed char* str );
istream& operator>> (istream& is, unsigned char* str )

当然也可以测试如下:

if ((cin >> a) == cin) {
cout << "Equal" << endl; // Yes
} else { 
cout << "Not Equal" << endl; 
}
 

为什么可以使用cin作为真值判定条件


cin可以被如下使用:

if(cin){}
if(cin>>a>>b){}
while(cin>>a){}

上面说到了>>的返回值是cin,所里上面的真值判定等同于:

if(cin){}
if(cin){}
while(cin){}

如果cin的状态ok则为真,如果cin遇到eof或者发生错误则返回false, 为什么可以使用cin作为真值判定条件?

首先看cin是如何定义的:

extern istream cin;
这样的一个值怎么可以作为if的真值判定条件呢?这是因为在if(cin)或者while(cin)的时候,其实是调用了一个istream的方法,写一行简单的代码反汇编看一下:
int main() { 
    if(cin){} 
    return 0; 
}

对应的汇编代码如下:

未命名

其实所有派生自ios的类都可以被强制转换为一个指针,如果设置了错误标志位则指针为null,否则非null,测试如下代码:
#include <iostream>
#include <fstream>
using namespace std;
 
int main () {
  ifstream is;
  is.open ("test.txt");
  if ( (void*)is == 0)// Equal to if(is)
    cerr << "Error opening 'test.txt'\n";
  return 0;
}

 

目录
相关文章
|
5月前
|
JavaScript 前端开发
不要混淆 typeof 的值运算和类型运算
不要混淆 typeof 的值运算和类型运算
27 0
|
存储 C语言
【C语言】 条件操作符 -- 逗号表达式 -- []下标访问操作符,()函数调用操作符 -- 常见关键字 -- 指针 -- 结构体
【C语言】 条件操作符 -- 逗号表达式 -- []下标访问操作符,()函数调用操作符 -- 常见关键字 -- 指针 -- 结构体
|
7月前
[题]写一个函数返回参数二进制中1的个数。
[题]写一个函数返回参数二进制中1的个数。
29 1
|
7月前
|
存储 C语言
学习总结(位操作符;循环输入的三种方式;交换两个变量值的三种方法;打印数字对应的二进制;unsigned int 与int 的区别;改变特定位数0/1;&&和||的连续操作(与前置,后置结合))
学习总结(位操作符;循环输入的三种方式;交换两个变量值的三种方法;打印数字对应的二进制;unsigned int 与int 的区别;改变特定位数0/1;&&和||的连续操作(与前置,后置结合))
69 0
|
编译器 C语言 C++
学C的第十六天【操作符详解:9. 条件操作符;10. 逗号表达式;11. 下标引用,函数调用和结构函数;12.表达式求值:整型提升、算术转换、操作符的属性;练习:使用函数完成整型函数的打印、元素逆置】-2
12.表达式求值 1. 表达式求值的顺序一部分是由操作符的优先级和结合性决定。 2. 有些表达式的操作数在求值的过程中可能需要转换为其它类型。
104 0
|
数据安全/隐私保护 C语言
【C语言】交换两个int变量的值,不能使用第三个变量
交换两个int变量的值,不能使用第三个变量。即a=3,b=5,交换之后 a=5,b=3
函数返回参数二进制中 1 的个数。
写一个函数返回参数二进制中 1 的个数。
|
JavaScript 前端开发
使用 JavaScript 中的变量、数据类型和运算符,计算出两个 number 类型的变量与一个 string 类型的变量的和,根据 string 类型处于运算符的不同位置得到不同的结果
使用 JavaScript 中的变量、数据类型和运算符,计算出两个 number 类型的变量与一个 string 类型的变量的和,根据 string 类型处于运算符的不同位置得到不同的结果
140 0
使用 JavaScript 中的变量、数据类型和运算符,计算出两个 number 类型的变量与一个 string 类型的变量的和,根据 string 类型处于运算符的不同位置得到不同的结果
宏#define的三种基本定义方式:固定值,表达式,运算符。
宏#define的三种基本定义方式:固定值,表达式,运算符。
 宏#define的三种基本定义方式:固定值,表达式,运算符。