cout顺序,i++和++i
先看下以下代码
#include<iostream>
using namespace std; int x = ; int f1()
{
x = ;
return x;
} int f2()
{
x = ;
return x;
} int main()
{
//Test1
cout << x << ' ' << f1() << ' ' << f2() << endl; //2 2 3 //Test2
int i = ; cout << i++ << ' ' << i << ' ' << ++i << endl; //1 2 2 //Test3
int s[] = {, , }; int *p = s; //cout << *p << ' ' << *(p++) << ' ' << *(++p) << endl; //3 2 3 //cout << *p++ << ' ' << *++p << ' ' << *p << endl; //2 3 3 //cout << *p << ' ' << *++p << ' ' << *p << endl; //2 2 2 //cout << *++p << ' ' << *p << ' ' << *++p << endl; //3 3 3 //cout << *p++ << ' ' << *p << ' ' << *p++ << endl; //2 3 1 //cout << *p << " " << *p++ << " " << *p << endl;//2 1 2
}
- 首先先明白运算符重载:
ostream & operator <<(ostream &stream, T &t)
返回的是一个ostream类型的引用,为什么要返回引用,先留着待会说。
- 然后,cout是什么,是一个ostream类的对象。
- 接着,cout<<a;的实质是cout对象调用其成员函数operator<<(),即cout.operator<<(a),返回一个ostream类型的引用
- 那么cout << a << f();其实就是cout.operator<<(a).operator<<(f())。(可以把cout.operator<<(a)看成一个新的cout)
- 问题来了,cout是从右到左读取参数,如果参数是函数,则先执行函数体,再将返回的值压栈,否则直接将值压栈,最后再将栈中的值输出来(见上述例子的第一个输出)
- 如果涉及i++和++i呢,问题就变得更加复杂。因为不同的编译器有不同的输出结果啊!这里选的是vs2013。这里先要明白什么是i++和++i
T operator ++() //++var
{
var = var+;
return var;
}
T operator ++(int dummy) //var++(dummy)
{
T tmp = var;
var = var+;
return tmp;
}可以看到,++i比i++更有效率(少了一句T tmp=var;)
- 那么同样,cout是从右到左读取参数,若遇到i++,则立即将i的值压栈(注意是值,而不是i的引用),再执行i+1;若遇到++i,则先执行i+1,再将i的引用压栈(而不是i的值,是引用!!!);若遇到i,则将i的引用压栈。
- 最后一个问题,为什么
ostream & operator <<(ostream &stream, T &t)
要返回一个引用类型呢?如果不返回引用类型而是返回一个ostream对象的话,那么cout << a << b这样的式子就会有问题,编译不会通过的,因为cout<<a返回了一个ostream的对象,而这个对象是一个“值”,而不是一个“变量”,它不能作为左值。(比如a = 1是正确的,而1 = 1是错误的,因为1是一个值,而不是变量,不能作为左值)。
- 至此,上面的代码为什么会输出这些奇怪的结果就一目了然了,值得吐槽的一点是,这些跟编译器有关,研究起来很没意思,Anyway,搞清楚了还是挺开心的^^
cout顺序,i++和++i的更多相关文章
- c++顺序表基本功能
头文件 #define LIST_MAX_SIZE 5#define LISTINCREMENT 2#include<assert.h>#include<string>temp ...
- C++中如何建立一个顺序表
准备数据 #define MAXLEN 100 //定义顺序表的最大长度 struct DATA { char key[10]; //结点的关键字 char name[20]; int age; }; ...
- C++ 数据结构学习一(顺序表)
//SequentialList.h 顺序表模板类 #ifndef SEQUENTIAL_LIST_HXX#define SEQUENTIAL_LIST_HXX using std::cout; us ...
- 数据结构C++实现代码-顺序表
参考:https://blog.csdn.net/ebowtang/article/details/43094041 //seqList.h// //包含顺序表中的声明// #include<i ...
- 线性表之顺序表C++实现
线性表之顺序表 一.头文件:SeqList.h //顺序线性表的头文件 #include<iostream> ; //定义顺序表SeqList的模板类 template<class ...
- C++实现顺序查找,折半查找,插值查找
1.顺序查找 从数组起始扫描到数组结尾,判断该索引数组是否和关键字相等,成功返回1 代码如下: //顺序查找 int seqSearch(int *array, int low, int high, ...
- STL之set(唯一且有顺序)
set作为一个容器也是用来存储同一数据类型的数据类型,并且能从一个数据集合中取出数据, 在set中每个元素的值都唯一,而且系统能根据元素的值自动进行排序.应该注意的是set中数元素的值不能直接被改变. ...
- 数据结构实验1:C++实现静态顺序表类
写了3个多小时,还是太慢了.太菜了! 图1 程序运行演示截图1 实验1 1.1 实验目的 熟练掌握线性表的顺序存储结构. 熟练掌握顺序表的有关算法设计. 根据具体问题的需要,设计出合理的表示数据的顺序 ...
- C++顺序表(模板总结)
C++顺序表(模板总结) 总结: 1.模板类的实质是什么:让程序员写出和类型无关的代码 2.模板的对象时什么:方法或者类 3.是对类中的一系列操作,提供一个不固定数据类型的方法 用模板做的类的时候要指 ...
随机推荐
- vue打包后出现一些map文件的解决方法
Vue打包后出现一些map文件的解决办法: 问题: 可能很多人在做vue项目打包,打包之后js中,会自动生成一些map文件,那我们怎么把它去掉不要呢? 1.运行 cnpm run build 开始 ...
- 【微信小程序】转载:微信小程序实战篇-下拉刷新与加载更多
下拉刷新 实现下拉刷新目前能想到的有两种方式 1. 调用系统的API,系统有提供下拉刷新的API接口 当然,你可以直接在全局变量app.json的window里面配置上面这个属性,这样整个项目都允许下 ...
- CentOS7 升级到7.4
2 升级CentOS7.4 自己电脑上的系统还是CentOS7.2,服务器是CentOS7.3, 打算统统升级到最新版 升级前查看 > lsb_release -a LSB Version: : ...
- 十五套专为开发人员打造的PHP资源库
转载自:http://developer.51cto.com/art/201508/488143.htm 1)Mink Mink是一套PHP 5.3库,用于在测试当中模拟Web应用程序与浏览器之间的交 ...
- Win7各个版本之间的区别
Windows7包含6个版本,分别为Windows7 Starter(初级版).Windows7 Home Basic(家庭普通版).Windows7 Home Premium(家庭高级版).Wind ...
- 运行第一个.net core程序
前置条件 ubuntu已安装.net core运行环境 分6步 mkdir netcore 创建一个项目文件夹 cd netcore 进入该文件夹 dotnet new new命令 用于创建一个 ...
- Js日常笔记之this
在javascript中自己创建构造函数时可以利用this来指向新创建的对象上.这样就可以避免函数中的this指向全局了,如下 var x = 2; function test(){ this.x = ...
- jms、amqp、mqtt区别与联系
消息传递作为基本通信机制已经在全世界成功运用.无论是人与人.机器与人还是机器与机器之间,消息传递一直都是唯一常用的通信方式.在双方(或更多)之间交换消息有两种基本机制. 同步消息传递 异步消息传递 同 ...
- Wpf 抽屉效果
在android开发中有抽屉效果,就是在页面的边上有一个按钮,可以通过点击或者拖拽这个按钮,让页面显示.Wpf也可以实现相同的效果. 主要是通过一个DoubleAnimation和RectAnimat ...
- Docker Python API 与 Docker Command
span.kw { color: #007020; font-weight: bold; } code > span.dt { color: #902000; } code > span. ...