cout输出流的执行顺序

2024-03-24 08:32
文章标签 输出 执行 顺序 cout

本文主要是介绍cout输出流的执行顺序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

下面是IBM的一道笔试题

#include <iostream> 
using namespace std; int fun( ) 
{ 
cout << "f" ; 
return 1; 
} 
int main() 
{ int i = 1; 
// cout << i++ << i++ << i++ << endl; 
cout << "m" << fun() << fun() << fun() << endl; 
return 1; 
} 

输出fffm111
问题:cout这种连接写法的输出的执行顺序是啥呢?

cout<<"m"<<fun1()<<fun2()<<fun3()<<endl;
<<运算是左结合的。
必然先求cout<<”m”的值,值仍然是cout
然后试图求cout<< fun1()的值,这必须先求出fun1()的值。整个表达式的值仍然是cout
然后试图求cout<< fun2()的值,这必须先求出fun2()的值。整个表达式的值仍然是cout
然后试图求cout<< fun3()的值,这必须先求出fun3()的值。整个表达式的值仍然是cout
最后是cout<< endl的值,值是cout
整个表达式语句以分号结尾
注意:问题就在这里:“这必须先求出fun1()的值”,“这必须先求出fun2()的值”,“这必须先求出fun3()的值”,这3句。这是计算<<运算的前提。只要分别在计算cout<< fun1(),cout<< fun2(),cout<< fun3(),之前完成就可以了。
因此,具体是先计算fun1()的值,还是先计算fun2()的值,还是先计算fun3()的值,还是先计算cout<<”m”的值,都不影响表达式的值。
问题就在这里:
这是个<<表达式。<<本来是位运算,但是这里cout却是来利用运算的“副作用”。
所谓副作用,就是计算一个表达式的时候,除了得到它的值以外,对环境产生的影响都是副作用。
比如:

int a=1,b=2,c=3,d; d=a<<b:
这一步,a<

int foo(int a, int b) { return a+b; } 
int bar(int a, int b) { return a-b; } 
int a=1,b=2,c=3,d; 
d=foo(a,b)+bar(b,d); 

这里,foo()和bar()都没有副作用。因此,这个表达式,不论是先计算foo(a,b)的值,还是先计算bar(b,c)的值,都不会影响计算的结果。
但是,如果是这个例子:

int foo(int* a) { (*a)++; return *a;} 
int bar(int* a) { (*a)--; return *a;} 
int a=5,b; 
b=foo(&a)+bar(&a); 

这个表达式,foo()和bar()都有副作用,所以,先计算foo(&a)还是先计算bar(&a),将直接影响到b的值。
假如先计算foo,再计算bar。
首先,a=5
计算foo(&a),a变成6,foo(&a)的值是6
计算bar(&a),a变成5,bar(&a)的值是5
这样,b=6+5=11
假如先计算bar,再计算foo。
首先,a=5
计算bar(&a),a变成4,foo(&a)的值是4
计算foo(&a),a变成5,bar(&a)的值是5
这样,b=5+4=9
这就造成了计算结果不一致。
===
那。。。怎么办
一般来说,编c/c++程序有一个纪律:一个语句中不要有两个表达式有副作用。
典型的这类行为包括:b=(a++)+(a++)+(a++);
这是典型的违反这条纪律的行为。每个a++都有副作用(改变a的值)。整个表达式的值跟求值顺序直接相连。
还有就是

char* fun() { cout<<"q"; return ""; } 
cout<<"m"<<fun()<<fun()<<fun()<<endl; 

每个fun()都有副作用(向屏幕上显示字符)。因此效果直接与求值顺序相关。(而整个表达式的值我们根本就不关心。虽然我知道,值就是cout)。
======

在c/c++中,求值顺序是怎么样的?

不知道。

C/C++的规范中,求值顺序是不规定的。这是为了给编译器以优化的空间。

比如:

b=(a+2)+(a+2);,那么如果只计算一次a+2的值,而不是两次,那么计算量会大大降低。

因此,

不要在C语言里面做这种事情:

char* fun() { cout<<"q"; return ""; } 
cout<<"m"<<fun()<<fun()<<fun()<<endl; 

要这样:

char* fun() { return "q"; } 
cout<<"m"<<fun()<<fun()<<fun()<<endl; // 输出的一定是 "mqqq\n" 

这样更好:

string fun() { return string("q"); } 
cout<<"m"<<fun()<<fun()<<fun()<<endl; // 输出的一定是 "mqqq\n" 

这样就更好了:

string f="q"; // 隐式转换 
cout<<"m"<<fun()<<fun()<<fun()<<endl; // 输出的一定是 "mqqq\n" 

这应该只是个测验。我相信IBM的软件工程师们不会编出这种垃圾代码的。

代码稍微修改了下

#include <iostream> using namespace std; int fun(int i) 
{ cout << "f"<<i; return i; 
} 
int main() 
{ int i = 1; cout << i++ << i++ << i++ << endl; cout << "m" << fun(1) << fun(2) << fun(3) << endl; cin.get(); return 1; 
} 

输出结果:
321
f3f2f1m123

如果只针对题来说的话,实际是这样的
cout<<”m”<

这篇关于cout输出流的执行顺序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/841027

相关文章

maven 编译构建可以执行的jar包

💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」👈,「stormsha的知识库」👈持续学习,不断总结,共同进步,为了踏实,做好当下事儿~ 专栏导航 Python系列: Python面试题合集,剑指大厂Git系列: Git操作技巧GO

顺序表之创建,判满,插入,输出

文章目录 🍊自我介绍🍊创建一个空的顺序表,为结构体在堆区分配空间🍊插入数据🍊输出数据🍊判断顺序表是否满了,满了返回值1,否则返回0🍊main函数 你的点赞评论就是对博主最大的鼓励 当然喜欢的小伙伴可以:点赞+关注+评论+收藏(一键四连)哦~ 🍊自我介绍   Hello,大家好,我是小珑也要变强(也是小珑),我是易编程·终身成长社群的一名“创始团队·嘉宾”

AI(文生语音)-TTS 技术线路探索学习:从拼接式参数化方法到Tacotron端到端输出

AI(文生语音)-TTS 技术线路探索学习:从拼接式参数化方法到Tacotron端到端输出 在数字化时代,文本到语音(Text-to-Speech, TTS)技术已成为人机交互的关键桥梁,无论是为视障人士提供辅助阅读,还是为智能助手注入声音的灵魂,TTS 技术都扮演着至关重要的角色。从最初的拼接式方法到参数化技术,再到现今的深度学习解决方案,TTS 技术经历了一段长足的进步。这篇文章将带您穿越时

jenkins 插件执行shell命令时,提示“Command not found”处理方法

首先提示找不到“Command not found,可能我们第一反应是查看目标机器是否已支持该命令,不过如果相信能找到这里来的朋友估计遇到的跟我一样,其实目标机器是没有问题的通过一些远程工具执行shell命令是可以执行。奇怪的就是通过jenkinsSSH插件无法执行,经一番折腾各种搜索发现是jenkins没有加载/etc/profile导致。 【解决办法】: 需要在jenkins调用shell脚

web群集--nginx配置文件location匹配符的优先级顺序详解及验证

文章目录 前言优先级顺序优先级顺序(详解)1. 精确匹配(Exact Match)2. 正则表达式匹配(Regex Match)3. 前缀匹配(Prefix Match) 匹配规则的综合应用验证优先级 前言 location的作用 在 NGINX 中,location 指令用于定义如何处理特定的请求 URI。由于网站往往需要不同的处理方式来适应各种请求,NGINX 提供了多种匹

Lua 脚本在 Redis 中执行时的原子性以及与redis的事务的区别

在 Redis 中,Lua 脚本具有原子性是因为 Redis 保证在执行脚本时,脚本中的所有操作都会被当作一个不可分割的整体。具体来说,Redis 使用单线程的执行模型来处理命令,因此当 Lua 脚本在 Redis 中执行时,不会有其他命令打断脚本的执行过程。脚本中的所有操作都将连续执行,直到脚本执行完成后,Redis 才会继续处理其他客户端的请求。 Lua 脚本在 Redis 中原子性的原因

如何将一个文件里不包含某个字符的行输出到另一个文件?

第一种: grep -v 'string' filename > newfilenamegrep -v 'string' filename >> newfilename 第二种: sed -n '/string/!'p filename > newfilenamesed -n '/string/!'p filename >> newfilename

Smarty模板执行原理

为了实现程序的业务逻辑和内容表现页面的分离从而提高开发速度,php 引入了模板引擎的概念,php 模板引擎里面最流行的可以说是smarty了,smarty因其功能强大而且速度快而被广大php web开发者所认可。本文将记录一下smarty模板引擎的工作执行原理,算是加深一下理解。 其实所有的模板引擎的工作原理是差不多的,无非就是在php程序里面用正则匹配将模板里面的标签替换为php代码从而将两者

Detectorn2预训练模型复现:数据准备、训练命令、日志分析与输出目录

Detectorn2预训练模型复现:数据准备、训练命令、日志分析与输出目录 在深度学习项目中,目标检测是一项重要的任务。本文将详细介绍如何使用Detectron2进行目标检测模型的复现训练,涵盖训练数据准备、训练命令、训练日志分析、训练指标以及训练输出目录的各个文件及其作用。特别地,我们将演示在训练过程中出现中断后,如何使用 resume 功能继续训练,并将我们复现的模型与Model Zoo中的

(function() {})();只执行一次

测试例子: var xx = (function() {     (function() { alert(9) })(); alert(10)     return "yyyy";  })(); 调用: alert(xx); 在调用的时候,你会发现只弹出"yyyy"信息,并不见弹出"10"的信息!这也就是说,这个匿名函数只在立即调用的时候执行一次,这时它已经赋予了给xx变量,也就是只是