转自: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中的区别的更多相关文章

  1. JAVA中自增自减运算符(i++与++i的区别)

    注意: 自增运算符和自减运算符只能用于变量,而不能用于常亮或表达式 运算符 运算 范例 结果 ++ 自增(前):先运算后取值 a=2;b=++a; a=3;b=3; ++ 自增(后):先取值后运算 a ...

  2. java和javascript中this区别的浅探讨

    今天在学习javascript的时候碰到了this,感觉它跟java里的有点不一样.然后上网查了一下,参考了这篇文章,JavaScript中this关键字详解,发现它们之间的区别主要是这样: java ...

  3. Java基础知识——算术操作符、自增自减、关系操作符,你真的了解吗?

    三人行,必有我师焉.欢迎大家加我的微信 yh18482155461,或扫描下方二维码,关注我的微信公众号,共同探讨Java相关技术问题. 温故知新 上一节我们讲到了Java中的赋值操作符,用案例的方式 ...

  4. 【Java】【4】关于Java中的自增自减

    摘要:理解j = j++与j = ++j的区别:正确用法:直接用j++,不要用前两种 正文: import java.util.*; public class Test{ public static ...

  5. java基础(二) 自增自减与贪心规则

    引言   JDK中提供了自增运算符++,自减运算符--.这两个操作符各有两种使用方式:前缀式(++ a,--a),后缀式(a++,a--).可能说到这里,说不得有读者就会吐槽说,前后缀式都挺简单的,前 ...

  6. Java运算符使用总结(重点:自增自减、位运算和逻辑运算)

    Java运算符共包括这几种:算术运算符.比较运算符.位运算符.逻辑运算符.赋值运算符和其他运算符.(该图来自网络) 简单的运算符,就不过多介绍使用了,可自行测试.关于赋值运算,可以结合算术运算和位运算 ...

  7. java入门---运算符&算术运算符&自增自减运算符&关系运算符&位运算符

        计算机的最基本用途之一就是执行数学运算,作为一门计算机语言,Java也提供了一套丰富的运算符来操纵变量.我们可以把运算符分成以下几组: 算术运算符 关系运算符 位运算符 逻辑运算符 赋值运算符 ...

  8. 023 01 Android 零基础入门 01 Java基础语法 03 Java运算符 03 算术运算符之——自增自减运算符

    023 01 Android 零基础入门 01 Java基础语法 03 Java运算符 03 算术运算符之--自增自减运算符 本文知识点:Java算术运算符中的自增自减运算符 自增自减运算符 之前我们 ...

  9. 【java从入门到精通】day-06-基本运算符-自增自减运算符

    1.运算符 java语言支持如下运算符: 算术运算符:+,-,*,/,%,++,-- 赋值运算符:= 关系运算符:>,<,>=,<=,==,!=,instanceof 逻辑运算 ...

随机推荐

  1. 小猿圈-IT自学人的小圈子 【强力推荐学习】

    笔记链接 https://book.apeland.cn/details/322/ 学习视频 https://www.apeland.cn/python

  2. Leetcode13. 罗马数字转整数Leetcode14. 最长公共前缀Leetcode15. 三数之和Leetcode16. 最接近的三数之和Leetcode17. 电话号码的字母组合

    > 简洁易懂讲清原理,讲不清你来打我~ 输入字符串,输出对应整数 ![在这里插入图片描述](https://img-blog.csdnimg.cn/63802fda72be45eba98d9e4 ...

  3. 【超值分享】为何写服务器程序需要自己管理内存,从改造std::string字符串操作说起。。。

    服务器程序为何要进行内存管理,管中窥豹,让我们从string字符串的操作说起...... new/delete是用于c++中的动态内存管理函数,而malloc/free在c++和c中都可以使用,本质上 ...

  4. GeoServer Rest服务启动匿名认证的配置方法

    GeoServer Rest服务数据默认需要进行用户名.密码的认证,如不需进行该认证,则启动匿名认证即可,配置方式如下(针对war包发布的GeoServer应用): 在GeoServer war包的解 ...

  5. 智能停车场车牌识别系统【python】

    百度AI:https://ai.baidu.com  申请App_id 代码重点:pip install  baidu_api from aip import AipOcr import os # 百 ...

  6. Python自动化测试面试题-Selenium篇

    目录 Python自动化测试面试题-经验篇 Python自动化测试面试题-用例设计篇 Python自动化测试面试题-Linux篇 Python自动化测试面试题-MySQL篇 Python自动化测试面试 ...

  7. 大数据学习(17)—— HBase表设计

    为啥要把表设计拿出来独立成章?因为我觉得像我这样搞了很多年Java后端开发的技术人员,在学习HBase的时候,会受到关系型数据库3NF.BCNF的影响.事实上,数据库范式在HBase里完全没用,必须转 ...

  8. 规模化敏捷 LeSS(三):LeSS Huge 是怎样炼成的?

    上篇文章< LeSS 团队实践指南>中讲到 LeSS 框架中的团队数量不要超过8个,但8个以上的团队要如何实践敏捷呢? 为了应对8个以上团队实践敏捷的情况,Bas 以及 Carig 还提出 ...

  9. flink clickhouse-jdbc和flink-connector 写入数据到clickhouse因为jar包冲突导致的60 seconds.Please check if the requested resources are available in the YARN cluster和Could not resolve ResourceManager address akka报错血案

    一.问题现象,使用flink on yarn 模式,写入数据到clickhouse,但是在yarn 集群充足的情况下一直报:Deployment took more than 60 seconds. ...

  10. MVVM窗体show的弹窗事件

    RestMatCutWin restMatCutWindow;//定义一个窗体的全局变量 private void RestMatCutWinExecute() { if (restMatCutWin ...