C++中cout语句背后的堆栈知识

C++中的cout是最常见的,假如cout后面有多个输出的话,他们的输出顺序是什么呢?决定他们输出顺序背后的原理是什么呢?先看下面的代码(1):

 1 #include<iostream>
 2 using namespace std;
 3 int abs(int a);
 4 int main()
 5 {    int a=-5;
 6     cout<<a<<endl<<abs(a)<<endl;
 7 }
 8 int abs(int a)
 9 {    cout<<"int a"<<endl;
10     return (a>=0?a:-a);
11 }

大家看一眼第6行的输出结果:很多人认为是-5

                                                        int a

                                                         5

可实际的结果是这样吗?看下图

图(1)

是不是与我们期望的不一样?

最后的输出结果与cout背后的汇编中堆栈有很大联系,我们知道汇编中堆栈是“后入先出”的存储区,执行第6行语句,从右向左依次把要输出的值压入堆栈,最后从上到下依次输出,第6行的汇编伪代码如下(以下代码不是严格意义上的汇编代码,为容易理解而写成):

push  endl;//把换行符压入

push  abs(a);//压入函数返回值,函数返回值压入堆栈需要两步:首先先执行cout<<"int a"<<endl;这行语句,故屏幕先显示出int a,然后计算a的绝对值并压入堆栈

push  endl;

push  a;输出a的值

到此所有的值都压入堆栈,并且此过程中执行其他语句(第9行)的输出结果在屏幕上已经显示出来,然后堆栈中的值依次出栈,在屏幕上先显示-5,再显示5;

假如还有点迷糊的话,再看一个例子(代码2):

 1 #include<iostream>
 2 using namespace std;
 3 int abs(int a);
 4 float abs(float b);
 5 int main()
 6 {    int a=-5;
 7     float c=-2.4f;
 8     cout<<"a="<<abs(a)<<endl<<"c="<<abs(c)<<endl;
 9     return 0;
10 }
11 int abs(int a)
12 {    cout<<"int abs"<<endl;
13     return(a>=0?a:-a);
14 }
15 float abs(float b)
16 {    cout<<"float abs"<<endl;
17     return(b>=0?b:-b);
18 }

假如还按照原来的感觉,那么输出顺序应该是a=int abs

                                                              5

                                                        c=float  abs

                                                             2.4

运行结果如下图:

图(2)

还是按照上面提到的汇编的方法分析下,压入堆栈的汇编伪代码如下:

push   endl;

push   abs(c);//需要强调的是这一步中 float abs立刻在屏幕中显示出来,无需等到所有的值压入堆栈完毕

push   c=;

push    endl;

push   abs(a);//这一步也立刻把int  abs显示出来,显示在float  abs下面

push   a=;

等上面所有的步骤执行完后,然后堆栈中的值依次出栈,最后的输出结果如图(2),代码(2)用到了重载函数,也是很有趣的知识。顺便提一句,在重载函数中,任意两个函数的参数表中函数的个数,各参数的数据类型和顺序不能完全一样,如int  func(int a,char b,float c)和double  func(int  d,char e,float f)。

                                                     

C++中cout语句背后的堆栈知识,古老的榕树,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。