c++与java区别的理解(二)--处理参数顺序和输出编译顺序

2020-09-29 17:18发布

     前几天碰到了一个很有趣的问题,就是关于c与java的处理参数顺序和输出编译顺序的不同,话不多说,先来看两个案例:

  1. #include<iostream>

  2. using namespace std;

  3. void print(int i,int j)

  4. {

  5. cout<<i<<" "<<j<<endl;

  6. }

  7. int main()

  8. {

  9. int i=0;

  10. print(++i,i++);

  11. i=0;

  12. print(i++,++i);

  13. return 0;

  14. }

输出为:


  1. public class test {

  2. public static void main(String args[]){


  3. int i=0;

  4. print(++i,i++);

  5. i=0;

  6. print(i++,++i);

  7. }

  8. public static void print(int a,int b){

  9. System.out.println(a+" "+b);

  10. }

  11. }

输出结果为:

     上述两份代码都是实现了相同的功能,即传入两个值并且将这两个值输出,然而可以看到,两者输出的值并不一样。这是因为java和c(包括c++)有着截然不同的处理参数顺序,c的编译器被设置为处理参数顺序也就是编译顺序是从右往左,而java恰好相反,是从左往右。

  根据这个规则,再来分析下代码,对c代码而言:

 print(++i,i++);

       从右往左编译,使得又因为i++先使用再增加的特性,所以第二个参数值传进去的是0,当编译到第一个参数值时,i的值为1,再加1就为2了,而java恰好相反,先对i自增为1,传入第二个参数也就为1.

   那么,为什么c要设计成这样,而不设计成java那样从左往右处理呢?这是由于两者的本质而引起的,c是编译型语言,而java则为半编译和半解释型语言,C或C++的编译器是被设计成从右向左的顺序处理函数调用中的变元的。但是编译器扫描变元的顺序是从左向右的。使用从左向右的顺序,编译器只需要一边扫描变元一边生成代码即可,但从右向左的顺序却要编译器记住扫描过的所有变元。为什么C++设计者不设计成从左向右的调用顺序呢,难道这是他们工作的疏忽吗,不是的。原因是为了处理那些变元也就是参数数目不固定的函数调用,更是为了减少编译以及执行的时间,试想一下,编译器是不知道这个函数具体有多少个参数的,从左往右执行会不断的推翻之前产生的代码,不如直接从右往左编译,一次性产生。

   而java为什么是从左往右呢?这是因为java虽然说是一种半解释型语言,其实实际上应理解为是一种解释型语言,它在编译代码的时候先生成.class文件,再交由jvm解释执行,而.class文件是在编译时产生的,java由于擦除的属性可不断的编译产生.class文件,而不像c一样编译成功后,执行的是.exe文件,只会编译一次。这个属性决定了java没必要从右往左编译。反正java在不断的擦除并产生新的.class文件,还不如直接从左往右的执行,更符合人的思维。java牺牲了自己执行的效率,换来了跨平台性(以上是博主本人的见解,如有错误,欢迎指正)

   Ps:1.现在c++也可以跨平台。

      2.解释性语言和编译型语言的区别;编译型语言写的程序执行之前,需要一个专门的编译过程,把程序编译成为机器语言的文件,比如exe文件,以后要运行的话就不用重新翻译了,直接使用编译的结果就行了(exe文件),因为翻译只做了一次,运行时不需要翻译,所以编译型语言的程序执行效率高,但也不能一概而论,部分解释型语言的解释器通过在运行时动态优化代码,甚至能够使解释型语言的性能超过编译型语言。解释则不同,解释性语言的程序不需要编译,省了道工序,解释性语言在运行程序的时候才翻译,比如解释性basic语言,专门有一个解释器能够直接执行basic程序,每个语句都是执行的时候才翻译。这样解释性语言每执行一次就要翻译一次,效率比较低。解释是一句一句的翻译。

  参照上述解释,其实很容易引出两者其它语句的编译顺序是否也一样,答案是true。比如输出的顺序:

  1. #include<iostream>

  2. using namespace std;

  3. int main()

  4. {

  5. int a=1,b=2,c=3;

  6. cout<<a+b+c<<" "<<++b<<" "<<++c<<endl;

  7. return 0;

  8. }

输出为 :


  1. public class test {

  2. public static void main(String args[]){

  3. int a=1,b=2,c=3;

  4. System.out.println((a+b+c)+" "+(++b)+" "+(++c));

  5. System.out.println("a="+a+" b="+b+" c="+c);

  6. }


  7. }

输出为:

   结果和猜想的一模一样。

作者:suye233

链接:https://blog.csdn.net/hackersuye/article/details/78881016

来源:CSDN
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。