c++与java区别的理解(二)--处理参数顺序和输出编译顺序
来源:互联网 发布:Ubuntu连不上WIFI 编辑:程序博客网 时间:2024/06/15 01:08
前几天碰到了一个很有趣的问题,就是关于c与java的处理参数顺序和输出编译顺序的不同,话不多说,先来看两个案例:
#include<iostream>using namespace std;void print(int i,int j){ cout<<i<<" "<<j<<endl;}int main(){ int i=0; print(++i,i++); i=0; print(i++,++i); return 0;}
输出为:
public class test {public static void main(String args[]){int i=0;print(++i,i++);i=0;print(i++,++i);}public static void print(int a,int b){System.out.println(a+" "+b);}}
输出结果为:
上述两份代码都是实现了相同的功能,即传入两个值并且将这两个值输出,然而可以看到,两者输出的值并不一样。这是因为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。比如输出的顺序:
#include<iostream>using namespace std;int main(){ int a=1,b=2,c=3; cout<<a+b+c<<" "<<++b<<" "<<++c<<endl; return 0;}
输出为:
public class test {public static void main(String args[]){int a=1,b=2,c=3;System.out.println((a+b+c)+" "+(++b)+" "+(++c));System.out.println("a="+a+" b="+b+" c="+c);}}
输出为:
结果和猜想的一模一样。
- c++与java区别的理解(二)--处理参数顺序和输出编译顺序
- java与C/C++字节顺序区别
- c语言实现一个正整数返回二进制参数的偶数位和奇数位顺序输出
- C语言中参数执行顺序及a++与++a实现的区别
- 深入剖析C函数参数的结合顺序及a++和++a的区别
- C/C++函数参数的入栈顺序,计算顺序和可变参数的实现
- C/C++函数参数的入栈顺序,计算顺序和可变参数的实现
- C/C++函数参数的入栈顺序,计算顺序和可变参数的实现
- HttpHandler和HttpModule的区别及处理顺序
- c/c++函数参数的入栈顺序和计算顺序
- <<与++的问题运算与输出顺序
- cout中表达式的先后执行顺序与输出顺序
- 顺序栈和链式栈的理解与使用
- c++高级---c语言中关于运算符优先级和运算符集合顺序的理解(*p++和*++p的区别)
- [C/C++]函数参数的入栈顺序与可变参数的实现
- [C/C++]函数参数的入栈顺序与可变参数的实现
- [C/C++]函数参数的入栈顺序与可变参数的实现
- [C/C++]函数参数的入栈顺序与可变参数的实现
- TCP C/S 聊天室项目初篇
- 导出shp
- .创建一个Rectangle类,添加width和height两个成员变量。 2.在Rectangle中添加两种方法分别计算矩形的周长和面积 3.编程利用Rectangle输出一个矩形的周
- kali linux不能进入win8和不能连网的修复过程
- Android 封装工具类之App
- c++与java区别的理解(二)--处理参数顺序和输出编译顺序
- is not a valid wheel filename
- neutron基本知识与图解
- leetcode 690. Employee Importance 深度优先遍历DFS
- 手机号发送验证码
- R语言之饼状图
- Android锁屏勒索病毒分析(4)秒抢红包
- SVM算法
- opencv3/C++基于颜色的目标跟踪