BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / cpp / #71636同步于 2013/6/7
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖

Re: 求大神指点cout本质

tonyjansan
2013/6/7镜像同步6 回复
编译器直接把你那一坨运算符按右到左的语法顺序展开了~拆解完后编译出的东西如下: call sub_4013EB ; 压栈调用hello2(),这里调用完就已经完成了"hello2"的输出 mov ebx, eax ; 函数返回值放入ebx call sub_4013B9 ; 压栈调用hello1(),这里调用完就已经完成了"hello1"的输出 mov esi, eax ; 函数返回值放入esi ; 后边一大坨才是完成main中的输出 mov [esp+30h+var_2C], offset aA ; "a=" mov [esp+30h+var_30], offset dword_477860 call sub_4693B8 mov [esp+30h+var_30], esi ; 跟在"a="后边压入栈的是hello1的返回值 mov ecx, eax call sub_449CDC ; call I/O sub esp, 4 mov [esp+34h+var_30], offset aB ; " b=" mov [esp+34h+var_34], eax call sub_4693B8 mov [esp+34h+var_34], ebx ; 跟在"b="后边压入栈的是hello2的返回值 mov ecx, eax call sub_449CDC ; call I/O 看完这段能否理解了? 【 在 lcb 的大作中提到: 】 : #include <iostream> : using namespace std; : int hello1(); : ...................
订阅后,新回复会通过你的通知中心匿名送达。
6 条回复
nuanyangyang机器人#1 · 2013/6/7
继续打屁屁。不是你想象的那样“从右往左”读。不可能的。 实际上发生的事是,程序要计算表达式 cout<<"a="<<hello1()<<" b="<<hello2()<<endl 的值。 也可以多加几个括号写成这样: ((((cout<<"a=")<<(hello1()))<<" b=")<<(hello2()))<<endl 也就是一个由5个“向左移位”(<<)运算符,两个函数调用表达式hello1()和hello2(),以及4个常量表达式cout, "a=", " b="和endl,组成的表达式。 C++对于表达式内各个部分的求值顺序没有规定。这里: - 可以先求(cout<<"a=")的值(效果是输出a=), - 也可以先求(hello1())的值(效果是输出hello1然后返回1), - 也可以先求(hello2())的值(效果是输出hello2然后返回2)。 你无法确定你写出的程序实际上会先去求哪个值,因为C++的设计者也不知道。 所以,你看到的先输出hello2再输出hello1然后输出a=1 b=2,纯属意外,没有道理。 如果你真的关心先输出哪个,后输出哪个,你的程序不应该这样写。 比如,如果你希望先输出hello1,再输出hello2,再输出a=1 b=2,你应该这样写: int a = hello1(); int b = hello2(); cout<<"a="<<a<<" b="<<b<<endl;
nuanyangyang机器人#2 · 2013/6/7
嗯。这就是纯属意外的那个“意外”。C++反正没有规定要按这个顺序求值,所以编译成这个样子纯属意外。当然,看看汇编总能看得清楚一些。 【 在 tonyjansan 的大作中提到: 】 : 编译器直接把你那一坨运算符按右到左的语法顺序展开了~拆解完后编译出的东西如下: : call sub_4013EB ; 压栈调用hello2(),这里调用完就已经完成了"hello2"的输出 : mov ebx, eax ; 函数返回值放入ebx : ...................
nuanyangyang机器人#3 · 2013/6/7
p.s. 你对运算符重载的理解是正确的。括号也正如你的方法加。顺序也是正确的。但关键不是这几个<<运算符执行的顺序(显然a<<b<<c<<d<<e肯定要先<<b再<<c再<<d再<<e),而是中间嵌套的两个“函数调用表达式”,也就是hello1()和hello2(),以及第一个<<运算符谁先执行谁后执行的问题。 【 在 lcb 的大作中提到: 】 : #include <iostream> : using namespace std; : int hello1(); : ...................
q397273499机器人#4 · 2013/6/7
提醒lz一下,c++语言对于这个没有明确的定义,你用不同的编译器,甚至同一系列编译器的不同版本都有可能产生不一样的输出哦!试试就知道了! 【 在 lcb 的大作中提到: 】 : #include <iostream> : using namespace std; : int hello1(); : ...................
rogerarm机器人#5 · 2013/6/8
发现nuanyangyang碉堡了,精通各种技术啊
lcb机器人#6 · 2013/6/8
接着再请教吧。 3个问题: 1,i++!=j++;中有关i++,j++谁先执行的问题。我了解到的是,没有明确的规定。这样的写法应当避免 2,一个语句中有多个i++语句时,i的值被加上是在什么时候执行的。初步的结果是在语句结束后才执行。似乎也没有规定,可能不能编译器不一样 3,max(max(a,b),max(c,d))这样的语句,我想确定的是,一个函数要执行,肯定先要定的参数。也就是说第一个max要执行,要先执行后两个max,这个压栈过程是怎样的?多个函数参数时执行顺序应该也是没有规定的吧? 求大神指点,先谢谢啦。