怎么产生这个问题的?
这个问题来自我们编译原理课上老师的提问,这个问题和编译时所采取的策略有关系。按道理说,无论是同一种语言,还是不同语言,在这个问题上的结果应该是不尽相同的。也就是:
#include<stdio.h>
int main()
{
int k=2;
printf ("%d %d %d",k++,++k,k);
}
这段代码用同一种语言不同的编译器,或者不同的语言,出来的结果可能不同。
首先我们来分析一下,这段代码理论上最有可能的结果,也就是在没有学过编译原理时,最有可能的结果是什么?
首先k=2;
当我们在输出第一个%d时,k++,这样的话,k是先参与运算的,所以第一个%d是没有++的,也就是2,++完就是3了
当我们在输出第二个%d是,++k,这样的话,k是先++,也就是K+1=3+1=4,然后用4参与运算的,所以应该输出4
当我们在输出第二个%d是,k,这样的话,可就直接输出了4;
综上所述,根据大一时的理论,这个结果按照上述分析结果应该是:2 4 4。
然后我们再来讲讲为什么提出了上述的问题,这个问题存在不确定因素的关键点在于没解释器或者编译器采取的编译策略。再具体一点就是,编译策略里面地压栈顺序。比如说,上面的分析时,我们默认了C语言的编译器的压栈顺序为从左向右,但是实际上C语言的编译器的压栈顺序一般都是从右向左的,这样的话,这个问题的结果就不确定了。这是理论上的结果,而且这个结果显然可能是更准确的一个结果。
基于以上的分析,我们不如直接来试试。
语言:C语言
运行环境:Win10
编译器:TDM-GCC 4.8.1 64-bit Release
语言:C语言
运行环境:Win10
编译器:TDM-GCC 4.8.1 32-bit Release
语言:JAVA语言
运行环境:Win10
编译器:JDK1.8.0_131
语言:C语言
运行环境:Android手机
编译器:TCC + uClibc
上面的4种环境,结果是不一样的,C语言在电脑上的结果是一样的,都是3,4,4,然而C语言在手机上其实是不一样的,是2,4,4。Java的结果是2,4,4。C++我不会,然后PHP不好做这样的测试,然后Python不能执行++这样的运算。
这个问题的出现原因是:
1.不同的语言的编译器在编译时所做的工作并不是完全相同的。主要是压栈的时候的顺序是不一样。
2.有的语言是在压栈之前就已经运算了,但是有的语言再压栈之后才让变量参与运算。
这个问提告诉我们,老师出题的时候要注意,这样的问题其实是没有答案的。除非你把编译的原理也一起出出来,否则是没有正确的答案的。
如果你有更合理的解释,欢迎你给我留言,我们可以一起讨论这个问题。