1. 算数运算符
算数运算符的注意事项:
①对于+运算符有三重含义:
- 加法运算;
- 表示正数;
- 字符串拼接:
例:
System.out.println(“hello” + ‘a’ + 1); // helloa1
System.out.println(‘a’ + 1 + “hello”); // 98hello(‘a’的ascii码是97)
System.out.println(“5+5=”+5+5); //5+5=55
System.out.println(5+5+"=5+5");//10=5+5
②对于“/”运算符:
当参与除法运算的除数和被除数,他们都是整数的时候,此时除法运算的结果会丢弃小数部分,只保留整数部分。
例:
int a=3;
int b=2;
int c = a / b;//c=1
double d = a / b; //d=1.0 相当于1 -> 1.0
//隐式类型转化
double e = 1.0 * a / b;//e=1.5
③ 对于“%”运算符:
int f = 5 % 3; //f=2
④对于“++”和“- -”:
⑴. ++,- -,他们都既可以放在变量之后(a++ ,b- -), 也可以被放在变量之前(++a, - -b);
⑵.当++ 或者 - -,他们不参与任何其他运算的时候,++或- -,在变量前或者变量之后是没有区别的;
⑶.但是一旦++或者- -,参与其他运算的时候,它们就会有一点区别。
对于++而言:
++在后,如 a++ + 1:首先a原本的值参与运算,a的值再自增1 ;
++在前,如++a + 1:参与运算的时候,首先自增,再参与运算。
即:
a++ + 1;//a原本的值参与运算,a的值再自增1
++a + 1;//a首先自增,再参与运算
例:
a = 4;
// 4 + 6 + 60
b = (a++) + (++a) + (a * 10);
2.赋值运算符
符号:= , +=, -=, *=, /=, %=。
其中=为基本的赋值运算符,其他的为扩展的赋值运算符。
注:a+=b和a=a+b的区别:
①a += b执行实际过程:先计算出a的值,然后用一个temp对象存储,之后和b进行相加,然后将值赋值给a引用。
②a = a+b 执行过程:先计算 a + b,然后再赋值给a引用,给a引用的时候如果 引用a 有计算过程,则会再次计算。
③+=如果两边的操作数的精度不一样时会自动向低转化,而a = a+b则不会自动转化,需要手动进行强制类型转化。
3.关系运算符
关系运算符的结果只有两种true or false。
注意和“=”区分不要把“==”写成“=”。
4.逻辑运算符
注意事项:
①关于数值范围的描述的表达,比如 1 < a < 10:a > 1 && a < 10
②单“&”与双“&&”的区别(短路):
&&比较智能,其具有短路功能,即发现运算符的第一个操作数已经是false时,第二个操组数(对应的表达式)不去管他,直接得到结果&&的结果false。
& 这种与运算,比较的死板,即使&第一个操作数,它已经是false,此时它仍然会计算第二个操作数(表达式),在把计算好的两个操作数的结果,做与运算,得到最终结果。
③异或(^) :同0异1。
5.位运算
注意事项:
左移运算(<<):相当于对操作数乘2(前提是移位后结果仍然在表示范围内)
带符号右移(>>):移位后高位补符号位,相当于给操作数除以2(只针对未溢出且可以除尽的情况)
无符号右移(>>>):移位后高位全部补0(通常用来处理正整数,对正整数而言相当于除以2)
异或(^):同0异1
性质1: 一个数和它自己异或运算的结果:a^a=0
性质2: 0和任何数做异或运算:0^a=a
例:请自己实现两个整数变量的交换
方法1:
temp=a;
a=b;
b=temp;
方法2:
a=a+b;
b=a-b;//a+b-b=a
a=a-b;//a+b-a=b
方法3:
a=a^b;
b=a^b;//a^b^b=a
a=a^b;//a^b^a=b
6.三目运算符
格式: 关系表达式 ?表达式1 : 表达式2
如果关系表达式结果为为true,运算后的结果是表达式1;
如果关系表达式结果为false,运算后的结果是表达式2;
注意:三目运算符的表达式1和表达式2一定是一个值而不能是一个操作。
7.补充
①用位运算符求一个整数(int)的绝对值:
import java.util.Scanner;
public class GetAbsoluteValue {
//方法一:通过负数求反加1求a的绝对值
public static int absoluteValue1(int a){
return a>=0 ? a : ~a+1;
}
//方法二:通过位运算求a的绝对值
public static int absoluteValue2(int a){
int b=a>>31;
return (a^b)-b;
}
public static void main(String[] args) {
int a=0;
System.out.println("输入一个int型整数:");
Scanner sc=new Scanner(System.in);
a=sc.nextInt();
System.out.println("方法1求"+a+"的绝对值为:"+absoluteValue1(a));
System.out.println("方法2求"+a+"的绝对值为:"+absoluteValue2(a));
}
}
②有三个int变量,a, b, c假设三个变量中有两个变量的值相同,请问如何快速求出,那个和其他两个变量不同的第三个变量的值?
public class GetDifferentValues {
/*
* 等价于:
* if(a==b) return c;
* else if(a==c) return b;
* else return a;
* */
public static int differentValues(int a,int b,int c){
return (a==b) ? c : (a==c) ? b : a;
}
public static void main(String[] args) {
int a=7,b=1,c=1;
System.out.println("和其他两个变量不同的第三个变量的值为:"+differentValues(a,b,c));
}
}
③任给一个int类型的正整数,如何判断该整数的值,是否是2的整数次幂
import java.util.Scanner;
public class JudgeNumbers {
public static boolean is2n(int a){
return ((~a + 1) & a) == a;
}
public static void main(String[] args) {
int a=0;
System.out.println("输入一个int型正整数:");
Scanner sc=new Scanner(System.in);
a=sc.nextInt();
if(is2n(a)==true)
{
System.out.println(a+"是2的整数次幂。");
}
else
{
System.out.println(a+"不是2的整数次幂。");
}
}
}
④一个十进制整数(int),的二进制表示形式(补码)中,包含的1个数? 比如0x80000000 中只包含一个1
import java.util.Scanner;
public class CountOneNumbers {
public static int countNumbers( int a){
int count=0;
for(int i=0;i<32;i++)
{
if((a>>>i&1)==1)//a有正负,所以选择无符号右移
{
count++;
}
}
return count;
}
public static void main(String[] args) {
int a=0;
System.out.println("输入一个十进制整数:");
Scanner sc=new Scanner(System.in);
a=sc.nextInt();
System.out.println(a+"的二进制补码形式中1的个数有"+countNumbers(a)+"个");
}
}
⑤有两个整数m,n,计算需要改变m的二进制表示(补码)中的多少位,才能得到n。比如10的二进制补码为1010,13的二进制补码表示为1101,那么至少需要改变1010中的3位才能得到1101。
import java.util.Scanner;
public class CountDifferentDigits {
public static void main(String[] args) {
int m=0,n=0;
int value=0;//存储m、n异或结果
System.out.println("输入两个整数m、n:");
Scanner sc=new Scanner(System.in);
m=sc.nextInt();
n=sc.nextInt();
value=m^n;
//直接调用第一题CountOneNumbers类中的countNumbers()方法统计异或结果中1的个数。
System.out.println(m+"需要改变"+CountOneNumbers.countNumbers(value)+"位才能得到"+n);
}
}