Java开发笔记(十)一元运算符的技巧

时间:2022-10-22 12:34:25

前面讲到赋值运算符的时候,提到“x = x+7”可以被“x += 7”所取代,当然Java编程中给某个变量自加7并不常见,常见的是给某变量自加1,就像走台阶,一般都是一级一级台阶地走,犯不着一下子跳上七级台阶。那么对于变量自加1的情况,既可以写成“x = x+1”,也可以写成“x += 1”,但是早期的Java设计师嫌前面的语句不够简洁,故而创造了新的运算符“++”,该运算符表示给变量自加1,于是“x += 1”可再简化为“x++”。同理,运算符“--”表示给变量自减1,语句“x--”等价于“x -= 1”和“x = x-1”。为深入理解“++”与“--”这两个运算符的作用,不妨运行下面的演示代码观察结果:

		int x = 3;
System.out.println("初始 x="+x);
x++; // 等同于x=x+1或者x+=1
System.out.println("自增1 x="+x);
x--; // 等同于x=x-1或者x-=1
System.out.println("自减1 x="+x);

既然有了自增1运算“++”和自减1运算“--”,那末有没有自乘运算“**”和自除运算“//”呢?很遗憾Java不存在所谓的自乘与自除,倘若自乘运算指的是求某整型变量的平方,还是老老实实地写以下代码“x = x*x”或者“x *= x”;倘若自除运算指的是求某整型变量的倒数,也要老老实实地写以下代码“double y = 1.0/x”。求平方与求倒数的代码如下所示:

		// 没有“**”这个运算符,求平方还是按照常规写法
x *= x; // 也可以写成x = x*x
System.out.println("求平方 x="+x);
// “//”已经被用作注释标记了,求倒数也得按照常规写法,而且整数的倒数只能是小数
double y = 1.0/x; // 注意这里的1.0/x,由于x是整型数,因此1/x无法求得小数
System.out.println("求倒数 y="+y);

由于“++”和“--”从头到尾只有变量自身参与运算,并无其它的操作数,因此又被称作一元运算符。类似的一元运算符还有负号运算符“-”和正号运算符“+”,这两个符号其实也来源于数学,都放在数字前面,比如“-1”表示负一,“+1”表示正一。但在Java编程当中,变量前面的正负号概念有所不同,例如“-x”指的是对x做负号运算,“x = -x”等价于“x = 0-x”。倘若整型变量x原来是正值,则负号运算的结果为负值;但若x原来是负值,则负号运算的结果变为正值,也就是所谓的负负得正。至于“x = +x”等价于“x = 0+x”,显然正号运算的结果与原值相同,正值的正号运算结果仍为正值,负值的正号运算结果仍为负值,而非数学上的正号意义。要想验证上述的正负运算符,可运行下列代码观察测试结果。

		x = -x; // 等同于x=0-x
System.out.println("负数 x="+x);
x = +x; // 等同于x=0+x
System.out.println("正数 x="+x);

注意到上面的正负运算符直接放在变量之前,实际上“++”和“--”也允许放在变量前面,单独的“++x”等价于“x++”,单独的“--x”等价于“x--”。之所以特别强调“单独”二字,是因为一旦它们放到了其他语句之中,运算结果就将大不相同。譬如下述代码演示了二者之间的区别:

		int y1 = 7;
int z1 = y1++; // 后加加操作的优先级较低
System.out.println("z1="+z1);
int y2 = 7;
int z2 = ++y2; // 前加加操作的优先级较高
System.out.println("z2="+z2);

运行上面的演示代码,会得到下面的日志信息。

z1=7
z2=8

可见此时z1的数值不等于z2,究其原因,乃是前加加与后加加的运行机制差异所致。对于“int z1 = y1++;”,该语句在执行时会分解成下列两个步骤:先执行对z1的赋值操作,再执行对y1的自增操作。此时最终的运行步骤如同以下代码:

    int z1 = y1;
y1 = y1+1;

对于“int z2 = ++y2;”,该语句在执行时也会分解成下列两个步骤:先执行对y1的自增操作,再执行对z1的赋值操作。此时最终的运行步骤如同以下代码:

    y2 = y2+1;
int z2 = y2;

其实这种情况很好理解,计算机语言跟人类文字的书写顺序一样,都是从上到下、从左往右。定睛一看“x++”,果然先看到变量x,接着才看到自增运算++;回头再瞅“++x”,这下先看到自增运算,然后才看到变量x。同是书面文字,计算机语言和人类语言的语法逻辑大抵相同。
最后来个脑筋急转弯,现有变量z1值为7,变量z2值为8,那么且看下面代码的运算结果,变量z3的数值又该为何?有兴趣的朋友不妨一试。

    int z3 = ++z1+z2++;

  

Java开发笔记(十)一元运算符的技巧的更多相关文章

  1. Java开发笔记(三十二)字符型与整型相互转化

    前面提到字符类型是一种新的变量类型,然而编码实践的过程中却发现,某个具体的字符值居然可以赋值给整型变量!就像下面的例子代码那样,把字符值赋给整型变量,编译器不但没报错,而且还能正常运行! // 字符允 ...

  2. Java开发笔记(三十八)利用正则表达式校验字符串

    前面多次提到了正则串.正则表达式,那么正则表达式究竟是符合什么定义的字符串呢?正则表达式是编程语言处理字符串格式的一种逻辑式子,它利用若干保留字符定义了形形色色的匹配规则,从而通过一个式子来覆盖满足了 ...

  3. Java开发笔记(三十九)日期工具Date

    Date是Java最早的日期工具,编程中经常通过它来获取系统的当前时间.当然使用Date也很简单,只要一个new关键字就能创建日期实例,就像以下代码示范的那样: // 创建一个新的日期实例,默认保存的 ...

  4. Java开发笔记(四十)日期与字符串的互相转换

    前面介绍了如何通过Date工具获取各个时间数值,但是用户更喜欢形如“2018-11-24 23:04:18”这种结构清晰.简洁明了的字符串,而非啰里八唆依次汇报每个时间单位及其数值的描述.既然日期时间 ...

  5. Java开发笔记(一百四十二)JavaFX的对话框

    JavaFX的对话框主要分为提示对话框和文件对话框两类,其中提示对话框又分作消息对话框.警告对话框.错误对话框.确认对话框四种.这四种对话框都使用Alert控件表达,并通过对话框类型加以区分,例如Al ...

  6. Java开发笔记(一百三十四)Swing的基本对话框

    桌面程序在运行过程中,时常需要在主界面之上弹出小窗,把某种消息告知用户,以便用户及时知晓并对症处理.这类小窗口通常称作对话框,依据消息交互的过程,可将对话框分为三类:消息对话框.确认对话框.输入对话框 ...

  7. Java开发笔记(八十九)缓存字节I/O流

    文件输出流FileOutputStream跟FileWriter同样有个毛病,每次调用write方法都会直接写到磁盘,使得频繁的写操作性能极其低下.正如FileWriter搭上了缓存兄弟Buffere ...

  8. Java开发笔记(八十八)文件字节I/O流

    前面介绍了如何使用字符流读写文件,并指出字符流工具的处理局限,进而给出随机文件工具加以改进.随机文件工具除了支持访问文件内部的任意位置,更关键的一点是通过字节数组读写文件数据,采取字节方式比起字符方式 ...

  9. Java开发笔记(八十六)通过缓冲区读写文件

    前面介绍了利用文件写入器和文件读取器来读写文件,因为FileWriter与FileReader读写的数据以字符为单位,所以这种读写文件的方式被称作“字符流I/O”,其中字母I代表输入Input,字母O ...

  10. Java开发笔记(八十五)通过字符流读写文件

    前面介绍了文件的信息获取.管理操作,以及目录下的文件遍历,那么文件内部数据又是怎样读写的呢?这正是本文所要阐述的内容.File工具固然强大,但它并不能直接读写文件,而要借助于其它工具方能开展读写操作. ...

随机推荐

  1. Oracle RAMN 备份解决方案一例

    以前在博客里面介绍了RMAN备份脚本一列分享,通过RMAN备份到本地路径,然后通过FTP将备份文件上传到FTP服务器. 下面简单介绍另外一例RMAN备份解决方案,下面是我简单画的一个图(很少画图,感觉 ...

  2. codeforces 505A. Mr. Kitayuta's Gift 解题报告

    题目链接:http://codeforces.com/problemset/problem/505/A 题目意思:给出一个长度不大于10的小写英文字符串 s,问是否能通过在字符串的某个位置插入一个字母 ...

  3. bzoj 3109: [cqoi2013]新数独

    #include<cstdio> #include<iostream> using namespace std; ][],li[][],xi[][],a[][],bh[][], ...

  4. iOS开发之网络数据解析(一)--JSON解析简介

    前言:对服务器请求之后,返回给客户端的数据,一般都是JSON格式或者XML格式(文件下载除外) 本篇随便先讲解JSON解析. 正文: 关于JSON: JSON是一种轻量级的数据格式,一般用于数据交互 ...

  5. oracle数据库导入导出dmp文件oracle命令

    在控制台下导入imp scott/密码@orcl file=文件路径 full=Y 导出 整个数据库TEST 用户名system  密码1234 exp system/1234@TEST file=文 ...

  6. VmWare问题解决(网络变更后虚拟主机无法上网)

    安装 Vmware,并新建一个虚拟机后,当时做好配置(NAT模式)后,虚拟机能够正常上网. 然后将电脑带到另一个地理位置办公时,却无法上网. 本篇探讨问题的缘由和几种解决方式. 一.缘由解析 仅探讨上 ...

  7. 2015ACM&sol;ICPC亚洲区沈阳站 B-Bazinga

    Bazinga Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Sub ...

  8. spring 容器的基础 XmlBeanFactory

    Spring容器最核心的两个类 DefaultListableBeanFactory  与 XmlBeanDefinitionReader ,XmlBeanFactory继承自DefaultLista ...

  9. Linux启动或禁止SSH用户及IP的登录,只允许密钥验证登录模式

    启动或禁止SSH用户登录 一般情况下,在使用Linux操作系统都不会去机房来操作机器,都是使用一些第三方的工具来操作. 比如使用SSH Secure File Transfer Client工具来传输 ...

  10. Core Json 序列化相关问题

    //返回json  大小写 配置            services.AddMvc()                    .AddJsonOptions( op => op.Serial ...