博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
通过一道面试题来看 C++ 语言中的表达式求值
阅读量:6490 次
发布时间:2019-06-24

本文共 2472 字,大约阅读时间需要 8 分钟。

hot3.png

题目一:
int
 a
=
10
,b
=
6
;
cout
<<
a
+
b
<<
"
 
"
<<
a
++<<
"
 
"
<<
b
++
请说出上述语句的执行结果。
很多人看过这段代码后估计都会直接就写上了 16 10 6 这样的结果吧,但上机实验的输出结果是: 18 10 6
为什么会出现这样的结果,下面是我的分析过程,如果有不对的地方请大家指正。
为了跟踪代码的执行步骤,我设计了一个类X,这个类是对int的模拟,行为方面与int基本一致,除了会打印出一些帮助我们理解的信息,代码如下:
class
 X
{
public
:
    X(){cout
<<
"
default construct
"
<<
endl;}
    X(
int
 a):i(a){ cout
<<
"
construct 
"
<<
i
<<
endl;}
    
~
X(){ cout
<<
"
desconstruct 
"
<<
i
<<
endl;}
    X(
const
 X
&
 x):i(x.i)
    {
        cout
<<
"
copy construct 
"
<<
i
<<
endl;
    }
    X
&
 
operator
++
()
    {
        cout
<<
"
operator ++(pre) 
"
<<
i
<<
endl;
        
++
i;
        
return
 
*
this
;
    }
    
const
 X 
operator
++
(
int
)
    {
        cout
<<
"
operator ++(post) 
"
<<
i
<<
endl;
        X x(
*
this
);
        
++
i;
        
return
 x;
    }
    X
&
 
operator
=
(
int
 m)
    {
        cout
<<
"
operator =(int)
"
<<
endl;
        i 
=
 m;
        
return
 
*
this
;
    }
    X
&
 
operator
=
(
const
 X
&
 x)
    {
        cout
<<
"
operator =(X)
"
<<
endl;
        i
=
x.i;
        
return
 
*
this
;
    }
    
/
    friend ostream
&
 
operator
<<
(ostream
&
 os,
const
 X
&
 x)
    {
        os
<<
x.i;
        
return
 os;
    }
    friend X 
operator
+
(
const
 X
&
 a,
const
 X
&
 b)
    {
        cout
<<
"
operator +
"
<<
endl;
        return
 X(a.i+b.i);
    }
    
//
public
:
    
int
 i;
};
然后执行以下代码:
    X a(
10
),b(
6
);
    cout
<<
"
sum:
"
 
<<
a
+
b
<<
"
 a:
"
<<
a
++<<
"
 b:
"
<<
b
++<<
endl;
使用GCC4。5编译后,代码的执行结果如下:
construct 10
construct 6
operator ++(post) 6
copy construct 6
operator ++(post) 10
copy construct 10
operator +
construct 18
sum:18 a:10 b:6
desconstruct 18
desconstruct 10
desconstruct 6
desconstruct 7
desconstruct 11
我们来简单分析下这个执行过程:
construct 10
construct 6  //这两行输出对应于 X a(10),b(6); 
operator ++(post) 6
copy construct 6 //表明首先执行了  cout<<"sum:" <<a+b<<" a:"<<a++<<" b:"<<b++<<endl;这句中的 b++这个表达式,
                              b++这个表达式返回了一个值为6的临时对象,而b本身则变成了7。
operator ++(post) 10 
copy construct 10  //这句的分析同上
operator +
construct 18 //对应于表达式 a+b ,可以看到,此时的a和b已经变成了11和7。表达式返回了一个值为18的临时对象。
sum:18 a:10 b:6 //输出的结果,从结果可以看出,实际上打印出的值分别为 a+b,a++和b++三个表达式所返回的临时变量。
desconstruct 18 //a+b 表达式返回的临时变量的析构
desconstruct 10 //a++ 表达式返回的临时变量的析构
desconstruct 6 //b++表达式返回的临时变量的析构
desconstruct 7 //变量a 的析构

desconstruct 11  //变量b的析构

真相大白了。为什么编译器会这样来编译这个表达式呢?

其实<<在同一语句中连续使用,其实本质上是函数的复合调用:
cout<<a+b<<" "<<a++<<" "<<b++; 
本质上是
operator<<(operator<<(operator<<(cout,a+b),a++),b++)
由于c++函数的参数的求值顺序是从右至左的(c++标准虽未规定,但是基本所有的编译器是这么干的),所以参数的计算次序是:
b++ //7
a++ //11
a+b //18
cout<<18
cout<<10 //因为10已经先入栈了
cout<<6//同上
上述实验的环境均为GCC4。5  据同学说VS2010执行的结果在DEBUG下和RELEASE下居然分别为:16 10 6 和18 10 6,不过我没有去验证过,有兴趣的同学可以去验证并分析一下。
附上一篇专门讲解C/C++表达式求值的文章。http://blog.csdn.net/luciferisnotsatan/article/details/6456696

转载于:https://my.oschina.net/u/90679/blog/109042

你可能感兴趣的文章
一个测试SQL2005数据库连接JSP档
查看>>
JspContext对象与PageContext对象
查看>>
java中间==、equals和hashCode差额
查看>>
TextureView+SurfaceTexture+OpenGL ES来播放视频(一)
查看>>
才一年,H5的发展就成这样了......
查看>>
McBsp接口使用和概念
查看>>
关于WEB Service&WCF&WebApi实现身份验证之WCF篇(1)
查看>>
类是公共,它应该被命名为.java文件声明
查看>>
介绍一个超好用的HICHARTS扩展插件
查看>>
中断相关一【转】
查看>>
MonkeyImage API 实践全记录
查看>>
LeetCode - Subsets
查看>>
可选链
查看>>
Docker CPU 资源限制——CPU分片功能测试
查看>>
FP-Growth算法之频繁项集的挖掘(python)
查看>>
基于Hibernate注解的解读
查看>>
ELK——安装 logstash 2.2.0、elasticsearch 2.2.0 和 Kibana 3.0
查看>>
Java内部DNS查询实现和参数设置
查看>>
MySQL批量SQL插入性能优化
查看>>
0c-37-ARC
查看>>