小心它----“复合赋值运算”

这是今天在开发当中遇到的问题,虽然不是很大,但还是花了一点时间去琢磨。

      嗯,好了。先看一段源代码: 

short value=2;

   value-=2;

     源码就是上面这个样子的,我动手写的时候因为理解的问题,把代码改成了这个样子:

short value=2;

value=value-2;

    这时候编译器就和我杠上了,报第二行有错。想想也对, value 变量和一个整型运算后 Java 会自动将运算结果提升到 int 类型,这和 value 定义的时候的 short 类型的产生矛盾。

 

提供的修改意见有两个:

    1)把 value的类型改为 int ;

    2)把value-2的运算结果强制转换为 short 类型;

第一段代码没有报错,那说明类型转换没有问题,就是说复合赋值运算里面有个偷偷摸摸类型转换的过程,但究竟是怎样转换的,采用的修改意见1)还是2)?

 

翻翻了手头的书,个人理解如下:

       第一段代码并不是我理解的:  value-=2  和 value=value-2 划等号;

      准确的表述应该是这样的:       value-2  等价于 value=(value 的类型) (value-2) ;

      所以说在复合赋值运算当中,会自动将他计算的结果值强制类型转换为左侧的类型。

      当然结果和左侧类型相同的时候就不会有任何的影响。

 

顺藤摸瓜,如果左边的类型要比计算结果的那个类型范围要小?肯定会丧失精确,造成Bug;

   比如:

short value=2;

//系统自动隐身的类型转换

value+=80000;

//从高位截断,发生了溢出,结果不是你想要的

System.out.println(valueA);

 

总结一下:

      优点:复合赋值运算方便,简单。而且很有效率,在性能上面也有优势;

      缺点:在你最不设防的精度问题上面背后给你一枪。

               所以在你运算符左边是个小范围而右边的运算结果是个大范围的时候,一定要小心。

 

 

 

作者:Orson 
出处:http://www.cnblogs.com/java-class/ 
如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】 
如果,您希望更容易地发现我的新博客,不妨点击一下左下角的【关注我】 
如果,您对我的博客内容感兴趣,请继续关注我的后续博客,我是【Orson】 

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段 声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 

转载:http://www.cnblogs.com/java-class/archive/2013/06/03/3115994.html

时间: 2024-12-29 00:02:24

小心它----“复合赋值运算”的相关文章

【C/C++学院】0820-Nullptr/const对象/类指针引用以及mallocfree与newde/类重载运算符/QT加法重载/类的重载赋值运算/自增在前在后差别/赋值重载深浅拷贝/重载下标

Nullptr #include<iostream> void go(int num) { std::cout << "gonum" << std::endl; } void go(void *p) { std::cout << "gop" << std::endl; } void main() { //void *p = nullptr; void *p = NULL;//C++是强类型,严格的类型检查

VC#2005快速入门之复合赋值操作符

快速入门 前面讲过如何使用算术操作符来创建新值.例如,以下语句使用操作符+来创建比变量answer大42的一个值,新值将写入控制台: Console.WriteLine(answer + 42); 前面还讲过如何使用赋值语句来更改一个变量的值.以下语句使用赋值操作符将answer的值变成42: answer = 42; 如果希望在一个变量的值上加42,可以将赋值操作符与加法操作符合并到一起.例如,以下语句在answer上加42,并将新值赋给answer.换言之,在运行该语句之后,answer的值

c++的问题-c++primer 第四版:在书店程序中,我们使用了加法操作符而不是复合赋值操作符

问题描述 c++primer 第四版:在书店程序中,我们使用了加法操作符而不是复合赋值操作符 c++primer 第四版:在书店程序中,我们使用了加法操作符而不是复合赋值操 作符将 trans 加到 total 中,为什么我们不使用复合赋 值操作符? 解决方案 先把代码贴出来看,我只看过C++ Primer Plus(第五版).

C++中的构造函数,拷贝构造函数和赋值运算

关于C++中的构造函数,拷贝构造函数和赋值运算,以前看过一篇<高质量C++/C编程指南>的文章中介绍的很清楚,网上能搜索到,如果想详细了解这方面的知识可以参看一下这篇文章. 常见的给对象赋值方式有构造函数,拷贝构造函数,赋值运算符这三种方法,如下代码演示了这几种常见的方法.     A a1;    A a2(a1);    A a3 = a1;    a3 = a2; 如果不手动写代码,C++编译器默认提供了构造函数,拷贝构造函数,赋值运算符的这三种方法的默认实现. 默认构造函数没有参数,它

赋值运算-不用三方变量,交换两个变量值。

问题描述 不用三方变量,交换两个变量值. 简单的: a=a+b; b=a-b; a=a-b; 这种好想起, 恶心点的比如要求最短: a^=b^; 谁解释下这个异或. 还有这个: a=b+(b=a)*0 这个深度怎么理解赋值执行顺序. 解决方案 如何交换两个变量值,不能用中间变量C语言交换两个变量值不利用额外变量 解决方案二: a=a+b; b=a-b; a=a-b; 解决方案三: 这里的异或是按位,值不同为1 比如 1^2 : 01 1 10 2 11 3 a=b+(b=a)*0 先计算括号里面

Flash action代码格式及规范

规范 Actions acript 的每行语句都以分号 ";" 结束. 不同于 BASIC 语言, Actions cript 语句同 C++, Java, Pascal 一样允许分多行书写, 即允许将一条很的长语句分割成两个或更多代码行, 只要在结尾有个分号就行了. 允许语句分行书写的唯一缺点是(至少对许多熟悉 BASIC 的人而言): 语句末尾不能忘记加分号. 语句分行唯一的限制是字符串不能跨行, 即两个分号必须在同一行. 分行书写长语句也是一个很好的排版办法, 例如下面的语句段(

Java编程那些事儿24—赋值运算符

4.4 赋值运算符 赋值运算符是指为变量或常量指定数值的符号.最基本的赋值运算符是"=". 由于Java语言是强类型的语言,所以赋值时要求类型必须匹配,如果类型不匹配时需要能自动转换为对应的类型,否则将报语法错误.示例代码: byte b = 12; //类型匹配,直接赋值 int n = 10; //类型匹配,直接赋值 double d = 100;//类型不匹配,系统首先自动将100转换成100.0,然后赋值 char c = -100; //类型不匹配,无法自动转换,语法错误 需

《C语言程序设计与实践(第2版)》——3.4 表达式和运算符

3.4 表达式和运算符 C语言的运算符范围很广,具有非常丰富的运算符和表达式运算,为编写程序提供了方便.表达式是由操作数和运算符组成,运算后产生一个确定的值,其中操作数可以是常量.变量.函数和表达式,每个操作数都具有一种数据类型,通过运算得到的结果也具有一种数据类型,结果的数据类型与操作数的数据类型可能相同,也可能不相同.运算符指出了表达式中的操作数如何运算.C语言中共有44种运算符,根据各运算符在表达式中的作用,表达式大致可以分成算术表达式.关系表达式.逻辑表达式.条件表达式.赋值表达式和逗号

《C++语言基础》实践项目——运算符重载(一)

返回:贺老师课程教学链接 [项目1-实现复数类中的运算符重载](1)请用类的成员函数,定义复数类重载运算符+.-.*./,使之能用于复数的加减乘除 class Complex { public: Complex(){real=0;imag=0;} Complex(double r,double i){real=r; imag=i;} Complex operator+(const Complex &c2); Complex operator-(const Complex &c2); Com