转:自增(自减)在Java与C中的区别
转自:http://seiyatime.blog.sohu.com/84358295.html
话说昨日面试,在笔试的25个选择题中,涉及自增自减不止一两题,以前在开发过程中并没太在意这方面的问题,也没接触到多复杂的自增(自减)表达 式,昨日一做,简直就是灾难,究其原因,主要还是在Java与C中自增(自减)存在很大的区别,下面就一个简单的例子来说明他们是如何处理的。
假定我们要计算表达式:
s1 = ( i++ )+( i++ )+( i++ ) 和 s2 = ( ++i )+( ++i )+( ++i )当i=3时的数值,对应的源程序如下:
JAVA源程序(Test.java)
public class Test{
public static void main(String[] args){
Test t = new Test();
int i = 3, s1, s2;
s1 = ( i++ )+( i++ )+( i++ );
i = 3;
s2 = ( ++i )+( ++i )+( ++i );
System.out.println("s1="+s1);
System.out.println("s2="+s2);
}
}
C语言源程序(Test.c)
void main ( ) {
int i = 3, s1, s2 ;
s1 = ( i++ ) + ( i++ ) + ( i++ );
printf ( "s1 = %d , i = %d", s1 , i );
i = 3 ;
s2 = (++i ) + (++i ) + (++i );
printf ( " s2 = %d , i = %d " , s2 , i );
}
运行结果
JAVA:
s1=12
s2=15
C:
s1=9 , i=6
s2=18 , i=6
从两种程序的源代码来看,求值的程序是类似的。但由上面的运行结果差异可见,自增(自减)运算符在Java语言中的求值方式与在C语言中的求值方式根本不同。
造成自增(自减)运算符在Java语言中与在C语言中的求值方式不同的原因是,两种语言的性质不同(C语言是面向过程的程序设计语言,而Java语言是面向对象的程序设计语言)。在C语言中变量的内存空间是在编译时分配的,而且在变量的生命周期内,一个变量名只对应一块内存区域。 如程序文件Test.C中的变量i,编译时分配内存并初始化为整数3。在计算表达式s1和s2的值时,首先要计算i++和++ i的值,根据自增(自减)运算符在前置和后置时的求值方式(前置时先计算后使用,后置时先使用后计算),在计算s1表达式的值时,变量i被引用三次参与加 法运算以后,才进行三次自增运算;而在计算s2表达式的值时,变量i三次自增运算以后的结果6,被引用三次参与加法运算,所以:
s1 = ( i++ ) + ( i++ ) + ( i++ ) = 3 + 3 + 3 = 9
s2 = ( ++i ) + ( ++i ) + ( ++i ) = 6 + 6 + 6 = 18
可见,在C语言的程序运行过程中,变量在每一次自增运算或赋值运算之后,其所对应内存区域中的内容就被重写,在变量的生命周期内的每一瞬间只能有唯一一个确定的值。
而在Java语言中,编译时并没有为变量分配内存,仅仅是创建了一种类型变量的对象模板,在类文件被解释执行时,每次都要为所执行到的变量创建一个 临时对象(分配内存)。如程序文件Test.java中的变量i,编译时并未分配内存,在运行时执行到赋值语句i = 3时,创建一个整型变量对象并初始化为3。在计算表达式s1和s2的值时,由于表达式的右端为三个自增运算表达式的和,对自增运算表达式而言,仍然与C语 言中一样,是前置时先计算后使用,后置时先使用后计算。变量I分别使用了三次,就会分别创建三个临时的整型变量对象,分配相应的内存空间,用来存储每次对 自增运算表达式的计算结果。所以:
s1 = ( i++ ) + ( i++ ) + ( i++ ) = 3 + 4 + 5 = 12
s2 = ( ++i ) + ( ++i ) + ( ++i ) = 4 + 5 + 6 = 15
可见,在Java语言的程序运行过程中,变量在每一次被引用时,都会创建相应的对象实例,分配相应的内存区域,其中的内容不会被重写,在变量的生命周期内的每一次引用就会有一个临时的实例对象被建立,它们的值互不影响。
通过上面的分析,很容易发现面向对象程序设计语言(如Java语言)与面向过程程序设计语言(如C语言)的区别,并能从中感受相同的运算符在使用时各自的不同特征,从而为语言的学习和运用奠定良好的基础。
转:自增(自减)在Java与C中的区别的更多相关文章
- JAVA中自增自减运算符(i++与++i的区别)
注意: 自增运算符和自减运算符只能用于变量,而不能用于常亮或表达式 运算符 运算 范例 结果 ++ 自增(前):先运算后取值 a=2;b=++a; a=3;b=3; ++ 自增(后):先取值后运算 a ...
- java和javascript中this区别的浅探讨
今天在学习javascript的时候碰到了this,感觉它跟java里的有点不一样.然后上网查了一下,参考了这篇文章,JavaScript中this关键字详解,发现它们之间的区别主要是这样: java ...
- Java基础知识——算术操作符、自增自减、关系操作符,你真的了解吗?
三人行,必有我师焉.欢迎大家加我的微信 yh18482155461,或扫描下方二维码,关注我的微信公众号,共同探讨Java相关技术问题. 温故知新 上一节我们讲到了Java中的赋值操作符,用案例的方式 ...
- 【Java】【4】关于Java中的自增自减
摘要:理解j = j++与j = ++j的区别:正确用法:直接用j++,不要用前两种 正文: import java.util.*; public class Test{ public static ...
- java基础(二) 自增自减与贪心规则
引言 JDK中提供了自增运算符++,自减运算符--.这两个操作符各有两种使用方式:前缀式(++ a,--a),后缀式(a++,a--).可能说到这里,说不得有读者就会吐槽说,前后缀式都挺简单的,前 ...
- Java运算符使用总结(重点:自增自减、位运算和逻辑运算)
Java运算符共包括这几种:算术运算符.比较运算符.位运算符.逻辑运算符.赋值运算符和其他运算符.(该图来自网络) 简单的运算符,就不过多介绍使用了,可自行测试.关于赋值运算,可以结合算术运算和位运算 ...
- java入门---运算符&算术运算符&自增自减运算符&关系运算符&位运算符
计算机的最基本用途之一就是执行数学运算,作为一门计算机语言,Java也提供了一套丰富的运算符来操纵变量.我们可以把运算符分成以下几组: 算术运算符 关系运算符 位运算符 逻辑运算符 赋值运算符 ...
- 023 01 Android 零基础入门 01 Java基础语法 03 Java运算符 03 算术运算符之——自增自减运算符
023 01 Android 零基础入门 01 Java基础语法 03 Java运算符 03 算术运算符之--自增自减运算符 本文知识点:Java算术运算符中的自增自减运算符 自增自减运算符 之前我们 ...
- 【java从入门到精通】day-06-基本运算符-自增自减运算符
1.运算符 java语言支持如下运算符: 算术运算符:+,-,*,/,%,++,-- 赋值运算符:= 关系运算符:>,<,>=,<=,==,!=,instanceof 逻辑运算 ...
随机推荐
- Leetcode13. 罗马数字转整数Leetcode14. 最长公共前缀Leetcode15. 三数之和Leetcode16. 最接近的三数之和Leetcode17. 电话号码的字母组合
> 简洁易懂讲清原理,讲不清你来打我~ 输入字符串,输出对应整数 Vuex的安装与使用
前言 每一个 Vuex 应用的核心就是 store(仓库).store基本上就是一个容器,它包含着你的应用中大部分的状态 (state).Vuex 和单纯的全局对象有以下两点不同: Vuex 的状态存 ...
- 每天五分钟Go - Map
map的定义 var m map[type]type fmt.Println(m) 此种方法定义的m为nil //打印的结果为: map[] map的创建 1.使用make创建 var m1 = ma ...
- Java中lombok @Builder注解使用详解(十八)
Lombok大家都知道,在使用POJO过程中,它给我们带来了很多便利,省下大量写get.set方法.构造器.equal.toString方法的时间.除此之外,通过@Builder注解,lombok还可 ...
- 如何反编译Python写的exe到py
参考链接: https://blog.csdn.net/qq_44198436/article/details/97314626?depth_1-utm_source=distribute.pc_re ...
- 货币兑换问题(贪心法)——Python实现
# 贪心算法求解货币兑换问题 # 货币系统有 n 种硬币,面值为 v1,v2,v3...vn,其中 v1=1,使用总值money与之兑换,求如何使硬币的数目最少,即 x1,x2,x3...xn 之 ...
- SpringCloud升级之路2020.0.x版-2.微服务框架需要考虑的问题
本系列为之前系列的整理重启版,随着项目的发展以及项目中的使用,之前系列里面很多东西发生了变化,并且还有一些东西之前系列并没有提到,所以重启这个系列重新整理下,欢迎各位留言交流,谢谢!~ 上图中演示了一 ...
- 大数据学习(21)—— ZooKeeper原理
这一篇我们对zookeeper的主要原理做一个简单介绍.zookeeper的核心原理是zookeeper atomic broadcast(ZAB协议),它来源于paxos协议.这里用通俗易懂的话,介 ...
- P6855「EZEC-4.5」走方格 TJ
目录 前言 题意简述 法一:时间复杂度 $Θ(m2n2)$ (TLE) $Code$ 法二:正解,时间复杂度 $Θ(mn)$ $Code$ 写在最后 洛谷 前言 题目传送门 正解:动态规划 挺 dul ...
- 攻防世界Web区部分题解
攻防世界Web区部分题解 前言:PHP序列化就是把代码中所有的 对象 , 类 , 数组 , 变量 , 匿名函数等全部转换为一个字符串 , 提供给用户传输和存储 . 而反序列化就是把字符串重新转换为 ...