当前位置:   article > 正文

Java深入浅出---------数据类型与变量、运算符、逻辑控制和输入输出

java深入浅出

前言

上一章中,我们初识了Java,知道了Java是一种面向对象的语言,也了解了Java的语言特性,也简单了解了main方法的组成。那么接下来这章就是主要解决Java与C大体相同但存在一些差异的细节的语法。



一、数据类型与变量

1、数据类型

  • 在Java中数据类型主要分为两类:基本数据类型引用数据类型

在这里插入图片描述

  • 在Java中,不论是16位系统还是32位系统,各个数据类型占用的内存大小都不会变。这也正印证了Java设计的初衷:“Write once, Run anywhere"。
数据类型关键字内存占用范围
字节型byte1字节-128~127
短整型short2字节-32768~32767
整型int4字节-231~231-1
长整型long8字节-263~263-1
单精度浮点数float4字节有范围,一般不关注
双精度浮点数double8字节有范围,一般不关注
字符型char2字节0~65535
布尔型boolean没有明确规定true 和 false

2、变量

  • 在程序中,除了有始终不变的常量外,有些内容可能会经常改变,对于这些经常改变的内容,在Java程序中,称为变量,而数据类型就是用来定义不同种类变量的。
  • 语法格式
    数据类型 变量名 = 初始值;
  • 整型变量
public class Main {
    public static void main(String[] args) {
        int a;
        System.out.println(a);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在这里插入图片描述
从这里可以看出,在Java中,变量在使用之前必须要赋初值,否则会编译不通过
int 的包装类型为 Integer
在给变量设置初始值时,值不能超过 int 的表示范围,否则会导致溢出,如果没有合适的初始值,可以设置为0.

  • 长整型变量
long b = 10L;
  • 1

长整型变量的初始值后加L,为了区分 int 和 long 类型。
long 的包装类型为 Long

  • 短整型变量
short a = 10;
  • 1

short 在任何系统下都占2个字节
short 的表示范围为:-32768~32767。
short 的包装类型为 Short

  • 字节型变量
byte b = 10;
  • 1

byte的范围是:-128~127。
byte 的包装类型是 Byte

  • 浮点型变量
    在Java中,int 除以 int 的值仍然是 int (会直接舍弃小数部分)。所以,如果想得到0.5,需要使用 double 类型进行计算。
double num = 1.1;
        System.out.println(num*num);
  • 1
  • 2

在这里插入图片描述
为什么最后会出现误差呢?
double 类型的内存布局尝试使用有限的内存空间表示可能无限的小数,势必会存在一定的精度误差,因此浮点数是个近似值,并不是精确值。
double 的包装类型为 Double

  • 单精度浮点型
float num = 1.0f;
  • 1

在数字后加 f 用来表示 float 类型。如果无 f ,默认认为是双精度浮点型

  • 字符型变量
char c = '帅';
  • 1

计算机中的字符本质上是一个整数,在C语言中使用 ASCII 表示字符,而Java中使用 Union 表示字符,因此一个字符占用两个字节,表示的字符种类更多,包括中文
==char 的包装类型为 Character ==。

  • 布尔类型
boolean b = true;
boolean c = false;
  • 1
  • 2

boolean 类型的变量只有两种取值,true 表示真,false 表示假
Java 的 boolean 类型和 int 类型不能相互转换,不存在1表示 true ,0 表示 false 这样的用法
boolean 的包装类型为 Boolean

  • 类型转换
    Java作为一个强类型编程语言,当不同类型之间的变量相互赋值的时候,会有严格的校验。在Java中,当参与运算数据类型不一致时,就会进行类型转换。Java中类型转换主要分为两类:自动类型转换(隐式)和强制类型转换(显式)

  • 自动类型转换(隐式)
    代码不需要经过任何处理,在代码编译时,编译器会自动进行处理。
    特点:数据范围小的转为数据范围大的时会自动进行

int a = 100;
long b = 10L;
b = a;//a和b都是整型,a的范围小,b的范围大,当将a赋值给b时,编译器会自动将a提升为long类型,然后赋值
a = b;//编译报错,long的范围比int范围大,会有数据丢失,不安全
  • 1
  • 2
  • 3
  • 4

编译器可以允许小范围赋值给大范围
Java当中,对于字面值的直接赋值是允许的,前提是没有超过表示范围,但是当超过表示范围之后,就会报错。

  • 强制类型转换(显式)
    强制类型转换:当进行操作时,代码需要经过一定的格式处理,不能自动完成。
    特点:数据范围大的到数据范围小的
int a = 10;
long b = 100L;
b = a;
a = (int)b;// long--->int,数据范围由大到小,需要强转,否则编译失败。
boolean flag = true;
flag = a;   //编译失败:类型不兼容
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

注意事项
1、不同数字类型的变量之间赋值,表示范围更小的类型能隐式转换成范围较大的类型。
小范围—(赋值给)—>大范围(编译器会自动进行处理)
2、如果需要把范围大的类型赋值给范围小的,需要强制类型转换,但是可能精度丢失
3、将一个字面常量进行赋值的时候,Java会自动针对数字范围进行检查
4、强制类型转换不一定能成功,不相干的类型不能互相转换。(例如boolean)

3、类型提升
  • int 与 long 之间:int 会被提升为 long
    在这里插入图片描述

上面产生编译错误的原因是从 long 转换到 int 可能会有损失,那是因为不同类型的数据之间相互运算时,数据类型小的会被提升到数据类型大的。在上面的示例中,a会被提升为 long ,当两个long 类型的数据相加仍是long ,编译器是不允许long 类型的数据赋给 int 类型的,所以要用long 类型来接收。

  • byte 与 byte 的运算
    在这里插入图片描述
    byte 和 byte都是相同类型的,但是出现编译报错,这是为什么呢?
    原因是,虽然a 和 b 都是byte 类型,但是计算a + b 会先将 a 和 b 都提升成 int ,再进行计算,得到的结果自然也是int 类型,所以要用int 类型的变量来接收。
    由于计算机的CPU通常是按照4个字节为单位从内存中读写数据,为了硬件上实现方便,诸如 byte 和 short 这种低于4个字节的类型,会先提升成int ,再参与计算
4、字符串类型

在Java中使用String 类定义字符串类型

		String s1 = "hello";
        String s2 = "world";
        System.out.println(s1 + s2);

        String s3 = 10 + 20 + "x";
        String s4 = "x" + 10 + 20;
        System.out.println(s3);
        System.out.println(s4);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

上面各自输出什么?
在这里插入图片描述
从结果可以看出,s3是先计算了后拼接,s4是之间拼接的。如果字符串在前,后面的直接拼接在后,如果字符串在后,那前面的就要先算。

  • int 转成 String
		int num = 10;
        String s1 = num + "";   //方法一
        String s2 = String.valueOf(num);   //方法二,调用String 这个类型的库方法
        System.out.println(s1);
        System.out.println(s2);
  • 1
  • 2
  • 3
  • 4
  • 5
  • String 转成 int
String str = "100";
int num = Integer.parseInt(str);  //调用Integer 的方法来实现转换
System.out.println(num);
  • 1
  • 2
  • 3

二、运算符

Java中的运算符和C语言的相差不大,在这么,我们就简单介绍一下。

1、算术运算符

  • 基本四则运算符:加减乘除取模(+ - * / %)
    都是二元运算符,使用时必须要有左右两个操作数
    int / int 结果还是int 类型,而且会向下取整
    做除法和取模时,右操作数不能为0
    % 不仅可以对整数取模,也可以对double 类型取模,但是没有意义,一般都是对整型取模的
    两侧操作数类型不一致时,向类型大的提升

  • 增量运算符(+= -= *= %=)
    这种类型运算符操作完成后,会将操纵的结果赋值给左操作数
    只有变量才能使用该运算符,常量不能使用
    在这里插入图片描述
    看上面的例子,按理说 b += a 可以转换成 b = b + a ,但是这里第二种却编译报错了。根据前面的规则,在运算第二个的时候,a会提升为long 类型,所以要用一个long 类型来接收,确实编译报错。但是第一个中,运算符会帮我们进行类型转换,也就是说转换成了 c = (int)(b + a)。

  • 自增/自减运算符(++ --)
    如果单独使用,【前置++】和【后置++】没有任何区别
    如果混合使用,【前置++】先自增,然后使用变量+1之后的值,【后置++】先使用变量原来的值,表达式结束时再给变量+1
    只有变量才能使用自增/自减运算符,常量不能使用,因为常量不允许被修改。

2、关系运算符

关系运算符主要有六个:==、!=、<、>、<=、>=
其计算结果是true 和 false

3、逻辑运算符(&& || !)

1、逻辑与(&&)
语法规则:表达式1 && 表达式2,左右表达式必须是boolean 类型的结果。(布尔表达式)
两个表达式都为真,结果才是真,只要有一个是假,结果就是假
2、逻辑或(||)
语法规则:表达式1 || 表达式2,左右表达式必须是boolean 类型的结果。(布尔表达式)
左右表达式只要有一个为真,结果就是真。
3、逻辑非( !)
语法规则:!表达式
真变假,假变真
4、短路求值
对于 && , 如果左侧表达式值为 false, 则表达式结果一定是 false, 无需计算右侧表达式
对于 ||, 如果左侧表达式值为 true, 则表达式结果一定是 true, 无需计算右侧表达式
& 和 | 如果表达式结果为 boolean 时, 也表示逻辑运算。但与 && || 相比, 它们不支持短路求值

5、位运算符

位运算符主要有四个: & | ~ ^ ,除 ~ 是一元运算符外,其余都是二元运算符。
位操作表示 按二进制位运算。 计算机中都是使用二进制来表示数据的(01构成的序列), 按位运算就是在按照二进制位的每一位依次进行计算。
1.按位与 &: 如果两个二进制位都是 1, 则结果为 1, 否则结果为 0
2.按位或 |: 如果两个二进制位都是 0, 则结果为 0, 否则结果为 1
3.按位取反 ~: 如果该位为 0 则转为 1, 如果该位为 1 则转为 0
4.按位异或 ^: 如果两个数字的二进制位相同, 则结果为 0, 相异则结果为 1
注意:
当 & 和 | 的操作数为整数(int, short, long, byte) 的时候, 表示按位运算, 当操作数为 boolean 的时候, 表示逻辑运算。

6、移位操作符

移位运算符有三个: << >> >>> ,都是二元运算符,且都是按照二进制比特位来运算的。
1.左移 <<: 最左侧位不要了, 最右侧补 0
2.右移 >>: 最右侧位不要了, 最左侧补符号位(正数补0, 负数补1)
3.无符号右移 >>>: 最右侧位不要了, 最左侧补 0
注意:

  1. 左移 1 位, 相当于原数字 * 2. 左移 N 位, 相当于原数字 * 2 的N次方
  2. 右移 1 位, 相当于原数字 / 2. 右移 N 位, 相当于原数字 / 2 的N次方
  3. 由于计算机计算移位效率高于计算乘除, 当某个代码正好乘除 2 的N次方的时候可以用移位运算代替。
  4. 移动负数位或者移位位数过大都没有意义。
7、条件运算符

条件运算符只有一个:
表达式1 ? 表达式2 : 表达式3
当 表达式1 的值为 true 时, 整个表达式的值为 表达式2 的值;
当 表达式1 的值为 false 时, 整个表达式的值为 表达式3 的值

也是 Java 中唯一的一个 三目运算符, 是条件判断语句的简化写法。

三、逻辑控制

1、分支结构

  • 1、if 语句
if(布尔表达式1{
	//语句1
}else if(布尔表达式2{
	//语句2
}else{
	//语句3
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

布尔表达式1成立,执行语句1;如果布尔表达式2成立,执行语句2;否则,执行语句3。
值得注意的是,只能执行三条语句中的一个。

例题:判断一个年份是否为闰年

 public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入你要查询的年:");
        int year = scanner.nextInt();
        if (year % 100 == 0) {
            if (year % 400 == 0) {             //判断是否为世纪闰年,是100的倍数,也是400的倍数
                System.out.println("是闰年!");
            } else {
                System.out.println("不是闰年!");
            }
        } else {
            if (year % 4 == 0) {             //判断是否为普通闰年,不是100的倍数,是4的倍数
                System.out.println("是闰年!");
            } else {
                System.out.println("不是闰年!");
            }
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

在这里插入图片描述

  • 2、switch 语句
    基本语法:
switch(表达式){
	case 1{
	语句1break}
	cese 2{
	语句2break}
	.......
	default{
	内容都不满足时执行语句;
	break}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

执行流程:

  1. 先计算表达式的值
  2. 和case依次比较,一旦有响应的匹配就执行该项下的语句,直到遇到break时结束
  3. 当表达式的值没有与所列项匹配时,执行default。

注意事项

  • 多个case后的常量值不可以重复
  • switch的括号内只能是以下类型的表达式:
    基本类型:byte、char、short、int,注意不能是long类型。
    引用类型:String常量串、枚举类型。
    float、double、long不能做switch 参数的数据类型。
  • switch不能表达复杂的条件
// 例如: 如果 num 的值在 10 到 20 之间, 就打印 hehe
// 这样的代码使用 if 很容易表达, 但是使用 switch 就无法表示.
if (num > 10 && num < 20) {
System.out.println("hehe");
}
  • 1
  • 2
  • 3
  • 4
  • 5

2、循环结构

  • while循环
while(循环条件){
	循环语句;
}
  • 1
  • 2
  • 3

循环条件为true时,则执行循环条件,否则结束循环。

示例:计算1!+2!+3!+4!+5!

 public static void main(String[] args) {
        int num = 1;
        int sum = 0;
        while(num <= 5){
            int ret = 1;
            int tmp = 1;
            while(tmp <= num){
                ret *= tmp;
                tmp++;
            }
            num++;
            sum += ret;
        }
        System.out.println(sum);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • for循环
    基本语法:
for(表达式1 ;布尔表达式 ; 表达式2{
	表达式3}
  • 1
  • 2
  • 3

表达式1:用于初始化循环变量初始值设置,在循环最开始时执行,且只执行一次。
布尔表达式:循环条件,满足则循环继续,否则循环结束。
表达式2:循环变量更新方式。

示例:计算1!+2!+3!+4!+5!

public static void main(String[] args) {
        int sum = 0;
        for (int i = 1; i <= 5; i++) {       //注意循环初始i和j要是1
            int tmp = 1;
            for (int j = 1; j <= i; j++) {
                tmp *= j;
            }
            sum += tmp;
        }
        System.out.println(sum);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • break
    break的功能是让循环提前结束。

  • continue
    continue的功能是跳过这次循环,立即进入下次循环。

四、输入输出

Java中的输入输出和C语言有很大的区别,所以我们要好好地学习一下。

  • 输出
System.out.println(args);      //输出一个字符串且自动换行
System.out.print(args);        //输出一个字符串,不带换行
  • 1
  • 2

println输出的内容自带 \n ,print 不带 \n 。

  • 从键盘输入
    使用 Scanner 读取字符串、整数和浮点数
import java.util.Scanner;       //需要导入 util 包,但是在IDEA中,编译器会自动导入
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);     //
        System.out.println("请输入你的姓名:");
        String name = sc.nextLine();            //nextLine:读入一行    
        System.out.println("请输入你的年龄:");
        String in = sc.next();                 //next:遇到空格结束
        int age = sc.nextInt();                 //nextInt:读入一个int类型的整数
        System.out.println("请输入你的工资:");
        float salary = sc.nextFloat();
        System.out.println("你的信息如下:");
        System.out.println("姓名: "+ name +"\n"+"年龄:"+ age +"\n"+"工资:"+ salary);
        sc.close();                 // 注意, 要记得调用关闭方法
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

要熟练掌握输入和输出的操作
nextLine:读入一行
next:遇到空格结束
nextInt:读入一个int类型的整数
hasNextInt:读取到了一个整数,则返回true


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/prog456/article/detail/62484
推荐阅读
相关标签
  

闽ICP备14008679号