cout 格式化输出的数据输出计算顺序与输出顺序不同吗?

cout 计算顺序问题
时间: 00:01:37
&&&& 阅读:92
&&&& 评论:
&&&& 收藏:0
标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&cout输出流的执行顺序
下面是IBM的一道笔试题
#include &iostream&&int fun( ) {&cout && "f" ; return 1; } int main() {&int i = 1; // cout && i++ && i++ && i++ && cout && "m" && fun() && fun() && fun() &&&return 1; }&输出fffm111&问题:cout这种连接写法的输出的执行顺序是啥呢?&cout&&"m"&&fun1()&&fun2()&&fun3()&&&&&运算是左结合的。 必然先求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&&b计算出1左移2位得到的结果。结果是4。也就是说,赋值表达式结束后,d的值变成4,其它地方都没有改变。这就是说这个&&运算没有副作用。&但是,cout&&"a"就不一样了。这个表达式的值我们根本就不关心。我们只关心,这个表达式&计算&完以后,"a"被输出到屏幕上了。这里&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()&&&每个fun()都有副作用(向屏幕上显示字符)。因此效果直接与求值顺序相关。(而整个表达式的值我们根本就不关心。虽然我知道,值就是cout)。&======&在c/c++中,求值顺序是怎么样的?&不知道。&C/C++的规范中,求值顺序是不规定的。这是为了给编译器以优化的空间。&比如:&b=(a+2)+(a+2);,那么如果只计算一次a+2的值,而不是两次,那么计算量会大大降低。&因此,&不要在C语言里面做这种事情:&char* fun() { cout&&"q"; return ""; }&cout&&"m"&&fun()&&fun()&&fun()&&&要这样:&char* fun() { return "q"; }&cout&&"m"&&fun()&&fun()&&fun()&& // 输出的一定是 "mqqq\n"&这样更好:&string fun() { return string("q"); }&cout&&"m"&&fun()&&fun()&&fun()&& // 输出的一定是 "mqqq\n"&这样就更好了:&string f="q"; // 隐式转换&cout&&"m"&&fun()&&fun()&&fun()&& // 输出的一定是 "mqqq\n"&但是这样不好吗?: cout&&"mqqq"&&&& 这应该只是个测验。我相信IBM的软件工程师们不会编出这种垃圾代码的。
代码稍微修改了下&#include &iostream&&&int fun(int i) { cout && "f"&&i; }&int main() {&int i = 1; cout && i++ && i++ && i++ && cout && "m" && fun(1) && fun(2) && fun(3) && cin.get(); return 1; }&输出结果: 321 f3f2f1m123
如果只针对题来说的话,实际是这样的&cout&&"m"&&fun()&&fun()&&fun();&对于&&其实是从右往左处理的。于是碰到fun()必然先输出f,然后返回1,于是就变成了&cout&&"m"&&fun()&&fun()&&1; 继续往左走,直到 cout&&"m"&&1&&1&&1 ;的时候已经输出了fff ,之后就是按顺序输出了m111, 所以看到的结果就是 fffm111&
系转载,原址:/penelope/articles/2426608.html标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&原文:/littleby/p/4529126.html
&&国之画&&&& &&&&&&
&& &&&&&&&&&&&&&&
鲁ICP备号-4
打开技术之扣,分享程序人生!1668人阅读
读书笔记(41)
问题(16)
#include&iostream&
#include&vector&
#include&string&
int main()
vector&string&
cout && &Enter strings!(Ctr+Z to the end)& &&
while(cin && word)
svec.push_back(word);
vector&string&::iterator iter1 = svec.begin(), iter2 = svec.end();
str = *iter1;
cout && &0: & && *iter1 &&
cout && &1: & && *iter1++ && &\t& && &2: & && *iter1++ && &\t& && &3: & && *iter1 && &\t&;
cout && &4: & && *iter1 &&
cin.clear();
运算结果:
Enter strings!(Ctr+Z to the end)
hello world just let them alone
1: world & & & &2: hello & & & &3: hello & & & &4: just
Process returned 0 (0x0) & execution time : 5.217 s
Press any key to continue.
分析:C/C++在函数调用时,默认都是右序入栈。
由以上测试可知:cout输出函数中多个表达式的执行顺序是从右到左,如上题cout && &1: & && *iter1++ && &\t& && &2: & && *iter1++ && &\t& && &3: & && *iter1 && &\t&;中,
第一步:执行最右边的表达式,将endl压入栈中;
第二步:解引用iter1取*iter1的值(这时iter指向svec中的第一个元素)压入栈中;
第三步:接着做iter1的自增操作(++自增操作符的优先级高于解引用操作符*)使iter1后移一位,这时iter1指向svec中第二个元素,同时返回*iter1(自增符号在右边时表达式取得是未自增前的iter指向的值,因此,这次返回的是svec中的第一个元素)并将其压入栈中
第四步:接着做iter1的自增操作,iter1(这时候是指向svec中的第二个元素)再次后移一位,指向svec中的第三个元素,同时返回*iter1(第三步中iter1自增后的值即指向svec中第二个元素),并将其压入栈中;
第四步:本条语句执行完毕,将栈中数全部输出,并且同时清空输出缓存(一般遇到endl时都会执行输出缓存的清空)。
最后执行cout && &4: & && *iter1 &&这时iter1是第四步中的自增会的值,因此,iter1这时指向的是svec中的第三个元素。
今天又在网上搜到了一篇讲解cout输出时入栈的问题讲解,很详细,特富有链接,很值得看啊……
这两个前半部分讲解的都一样,不过后半部分zhanghenglei的专栏有做了写补充。看过以后很有收获……
如果您对本文满意,请回复,谢谢^ . ^ . ^ . ^
同时欢迎提出宝贵意见,以帮助我改进,不胜感激!!!
——桑海整理
如果您对本文满意,请回复,谢谢^ . ^ . ^ . ^
同时欢迎提出宝贵意见,以帮助我改进,不胜感激!!!
——桑海整理
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:387362次
积分:1754
积分:1754
排名:第19910名
原创:47篇
转载:14篇
评论:44条
(4)(1)(2)(2)(3)(4)(1)(18)(26)使用“递归”算法实现单链表中数据的顺序和逆序输出,但不允许引入额外的空间复杂度。_编程_英汉互译
使用“递归”算法实现单链表中数据的顺序和逆序输出,但不允许引入额外的空间复杂度。
来源:|人气:338 ℃|类别:|时间: 17:24:36
问题:使用“递归”算法实现单链表中数据的顺序和逆序输出,但不允许引入额外的空间复杂度。
对这个熟悉的朋友请赐教一下.....#include &iostream&struct cc{ cc *};void display(cc *p)//正序{ if(p==NULL) cout&&p-&data&&&&; display(p-&np);}void display_(cc *p)//倒序{ if(p==NULL) display_(p-&np); cout&&p-&data&&&&;}cc *dz(cc *p)//倒置,先递归到链表最后,保存最后节点,然后在返回的过程中,把后结点指向前节点,并把前节点指针置空{ static cc *z; //if(!p || !p-&np){cout&&&error!&&&return 0;} if(p-&np-&np==NULL) z=p-&//保存最后节点 else dz(p-&np);//递归 p-&np-&np=p;//返回 p-&np=NULL;//返回最后结点}int main(){ cc s,*p; s.data=0; p=&s; for(int i=0; i&10; i++) //生成单链表 { p-&np= p-&np-&data=p-&data+1; p-&np-&np=NULL; p=p-& } display(&s); cout&& display_(&s); cout&& cc* z =dz(&s);//倒置 display_(z);//倒置后逆序输出 cout&& return 0;}热心网友
论文:递归算法在vb程序设计中的 实现 -中大网校论文网设计一个递归算法,删除不带头结点的单 链表 l中所有值递归算法实例:求阶乘j2se快速进阶——递归算法
||||点击排行C/C++---printf/cout 从右至左压栈顺序实例详解
时间: 00:27:46
&&&& 阅读:20
&&&& 评论:
&&&& 收藏:0
标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&__cdecl压栈顺序实例
明白计算:计算是从右到左计算的
栈和寄存器变量:x++,是将计算结果存放到栈空间,最后是要出栈的;而++x和x是将计算结果直接存放到某个寄存器变量中(是同一个),所以计算完最后输出时,++x和x的结果总是相同的。
??用个小例子来说明下:
printf("%d %d\n",x,x++);
printf("%d %d\n",y++,y);
printf("%d %d %d\n",z,z++,z);
printf("%d %d %d %d\n",w,++w,w++,w);
/*输出结果*/
7 7 5 7 标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&国之画&&&& &&
版权所有 京ICP备号-2
迷上了代码!

我要回帖

更多关于 cout 格式化输出 的文章

 

随机推荐