转自: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. PAT乙级:1070 结绳 (25分)

    PAT乙级:1070 结绳 (25分) 题干 给定一段一段的绳子,你需要把它们串成一条绳.每次串连的时候,是把两段绳子对折,再如下图所示套接在一起.这样得到的绳子又被当成是另一段绳子,可以再次对折去跟 ...

  2. 【转载】PHP 程序员进阶之路

    原文:没有Nginx,你还能做什么? PHP程序员的未来不是Java,Java拯救不了你. 已经1368年了,你扪胸自问,没有了Nginx的你,还能用PHP做什么.有一些高端的刁民会愤怒地说:&quo ...

  3. Python自动化测试面试题-经验篇

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

  4. Qt 入门 ---- 如何在程序窗口显示图片?

    步骤: 1. 选择资源(准备图片) 2. 加载资源(导入图片) 3. 使用资源(显示图片) 具体操作流程: ① 从网上寻找合适的图片素材,下载到本地,在项目根目录下创建一个images文件夹存储程序中 ...

  5. Android系统编程入门系列之界面Activity响应多元的属性动画

    在响应丝滑动画一篇文章中,分别介绍了作用于普通视图.绘制视图的绘制对象.和界面这三种对象的动画效果,但是都有一些使用的局限性.比如这些动画都只是以屏幕上绘制更新的方式绘制动画,并没有真实改变作用对象的 ...

  6. Spring in Action学习笔记(1)

    Spring基础 IoC 控制反转, 也称为DI-依赖注入 一.装配bean 推荐顺序:自动装配 -> JavaConfig装配 -> XML装配 1. 自动装配 @Component 注 ...

  7. sqli-labs靶机

    第一关   1' 第二关   1 第三关    1') 第四关    1'') 第五关   1'     +         extractvalue报错注入 第六关   1 "  +    ...

  8. vue中this.$router.push()路由传值和获取的两种常见方法

    1.路由传值   this.$router.push() (1) 路由跳转使用router.push()方法,这个方法会向history栈添加一个新纪录,所以,当用户点击浏览器后退按钮时,会回到之前的 ...

  9. Mybatis学习笔记-第一个Mybatis程序

    思路 搭建环境 搭建数据库(略) CREATE DDATABASE CREATE TABLE INSERT VALUES 新建项目 普通Maven项目 删除src文件夹 --> 建立父工程 导入 ...

  10. 建立局域网内使用的CentOS7源

    建立局域网内使用的CentOS7源 by 无若    1. 在CentOS下建立匿名的FTP访问服务 CentOS 7下安装配置pure-ftpd,并使用匿名用户登录 Pure-FTPd是Linux上 ...