2021-03-03

java的基础知识

程序结构

首先我们来看一下java程序

/**
*可以自动创建注释
*/
public class Hello{
	public static void main(String[] agrs){
		System.out.println("Hello World!");//执行码
		}
/*多行注释
多行注释开始
多行注释
多行注释结束	*/

}//class定义结束

java程序是面向对象的语言,所以一个程序的基本单位就是classclass是关键字,上诉程序的class的命名为Hello:

public class Hello{//Hello是类名,public是对类名的修饰
}

类名的命名规则:

1.类名必须以字母开头,后接字母,数字和下划线结合
2.习惯以大写字母开头
class的内部有众多的方法,如下

public static void main(String[] agrs){
}/*
其中public和static是对方法的修饰
void代表的方法的返回值为空
方法内的String[]是定义方法内的参数
*/

方法也有命名规则,命名和class一样也是以字母开头,习惯是以小字母开头后接字母,数字和下划线结合。
在方法的内部语句才是真正的执行码,java的每一句以分号结束

public class Hello{
	public static void main(String[] args){
		System.out.println ("Hello!");
		}
	}

注释:
这是单行注释

//单行注释

这是多行注释

/*
*/

特殊的多行注释

/**
*/

变量和数据类型

变量就是一个未知的量可以变化量,和我们在中学时代学习的变量一样,例如y=x+1其中yx就是变量。
java中定义了两种变量:基本类型变量引用类型变量

变量

首先我们来讨论基本类型变量,在java中变量必须先定义才能被使用,在使用变量时得先给它一个初始值,如:

int x=1;

这里int是对变量x的定义,本次定义的变量xint型,初始值为1。不写初始值的话就相当于给了变量一个默认值,默认值为0
下面来看一个完整的定义变量,然后打印变量

public class Test {
	public static void main(String[] args) {
	int x=100;//对变量x的定义
	System.out.println(x);//打印变量x

	}

}

运行的结果
打印出的结果为100
变量还有一个重要的特性就是可以重新赋值,例如先给变量x赋值100,后给变量赋值200

public class Test {
	public static void main(String[] args) {
	int x=100;//对变量x的定义
	System.out.println(x);//打印变量x
	x=200;//再次对变量赋值,为200
	System.out.println(x);//打印变量
	}

}

运行结果如下

可以看到第一次对变量赋值时已经对变量定义了,所以第二次对变量赋值时不需要对变量再次定义。
变量不仅可以重新赋值,还可以赋值给其他变量,如下代码:

public class Test {
	public static void main(String[] args) {
	int x=100;//对变量x的定义
	System.out.println("x ="+x);//打印变量x
	int y=x;//将变量x赋值给y,观察y输出是否与变量x一致
	System.out.println("y ="+y);//打印变量
	}

}

运行结果如下:
在这里插入图片描述
运行之后可以看出变量x的值与变量y值是一样的。
由此可以看出,变量可以反复赋值,这里需要提醒一下,这里的“=”与数学中的概念不同,这是一个赋值的意思。

基本数据类型

java定义了一下几种数据类型
整数类型:byte,short,int,long

浮点数类型:float,double

字符类型:char

布尔类型:boolean
java定义的这几类数据类型有什么区别呢?这个根据计算机的存储这些类型所占的字节数来区分的,大家都知道计算机的底层数据是以二进制这种形式存储的,而计算机最小存储单位为字节byte,而一个字节就是一个8位的二进制数,即8bit。它的二进制表示范围是000 000 00~111 111 11,换成10进制就是0255,16进制就是00ff
一个字节是1byte1024字节是1K1024K1M1024M1G1024G1T
不同的数据类型占用的字节数不一样。我们看一下Java基本数据类型占用的字节数:
java中数据类型所占的字节数

byte恰好就是一个字节,而longdouble需要8个字节。

整形

因为在计算机中第一个bit表示符号(0表示正,1表示负),各种类型的大致范围如下:

byte-128~127
short-32768 ~ 32767
int-2147483648 ~ 2147483647
long-9223372036854775808 ~ 9223372036854775807

我们来看一下定义的例子:

public class Test {
	public static void main(String[] args){
	byte i=-128;
	short i1=32767;
	int i2=-2147483648;
	long i3=9000000000000000000L;
	System.out.println("i="+i);
	System.out.println("i1="+i1);
	System.out.println("i2="+i2);
	System.out.println("i3="+i3);
	}
}

浮点型

浮点型数据就是小数,通常是用科学记数法表示的,所以小数点可以浮动,如1234.5可以表示成12.345*10^2
也可以表示成1.2345*10^3,所以称为浮点数。
下面是浮点数的定义:

public class Folat {

	public static void main(String[] args) {
		float f1=3.14f;
		float f2=3.14e38f;//科学记数法表示3.14*10^38
		double d1=1.97e307;
		double d2=-1.79e308;//科学记数法表示-1.79*10^308
		System.out.println("f1 ="+f1);
		System.out.println("f2 ="+f2);
		System.out.println("d1 ="+d1);
		System.out.println("d2 ="+d2);
	}

}

对于浮点型数据后面要加上f,最大可以表示10^38,而double最大可以表示
10^308

布尔类型

布尔类型只有truefalse两个值,布尔类型总是关系到运算的结果。
定义如下:


public class Boolean {

	public static void main(String[] args) {
		boolean b1=true;
		boolean b2=false;
		boolean isGerate=5>2;//5大于2,则运行的结果就为true
		boolean beGerate= 6<1;//6大于1,则运行结果就为false
		System.out.println("b1 ="+b1);
		System.out.println("b2 ="+b2);
		System.out.println("isGerate ="+isGerate);
		System.out.println("beGerate ="+beGerate);

	}

}

运行结果

字符类型

java中还定义了字符类型的数据char,就表示一个字符。Javachar类型除了可表示标准的ASCII外,还可以表示一个Unicode字符:
定义如下
在这里插入图片描述


public class Char {

	public static void main(String[] args) {
		
		char z='中';
		char g='国';
		char w='我';
		char a='爱';
		char n='你';
		System.out.println(z);
		System.out.println(g);
		System.out.println(w);
		System.out.println(a);
		System.out.println(n);

	}

}

运行结果如下
在这里插入图片描述

引用类型

除了上述基本类型的变量,剩下的都是引用类型。例如,引用类型最常用的就是String字符串:


public class Test {
	public static void main(String[] args){
	String s="Hello";
	System.out.println(s);
	}
}

常量

定义常量是需要在前面加上final定义如下:


public class Test {
	public static void main(String[] args){
	final double  pi=3.14;//pi是一个常量
	double r=2;
	double area=r*r*pi;
	pi=300;//显示错误
	System.out.println(area);
	}
}

变量的作用范围

Java中,多行语句用{ }括起来。很多控制语句,例如条件判断和循环,都以{ }作为它们自身的范围,只要正确地嵌套这些{ },编译器就能识别出语句块的开始和结束。
而在语句块中定义的变量,它有一个作用域,就是从定义处开始,到语句块结束。
超出了作用域引用这些变量,编译器会报错。
定义变量时,要遵循作用域最小化原则,尽量将变量定义在尽可能小的作用域,并且,不要重复使用变量名。

字符和字符串

java中字符和字符串是两种不同的数据类型。
字符
字符类型char是基本数据类型,它是character的缩写,也可以用Unicode来表示,一个字符可以保存一个Unicode字符。

char c='a';
char c1='中';

因为Java在内存中总是使用Unicode表示字符,所以,一个英文字符和一个中文字符都用一个char类型表示,它们都占用两个字节。要显示一个字符的Unicode编码,只需将char类型直接赋值给int类型即可:

int n1 = 'a'; // 字母“A”的Unicodde编码是97
int n2 = '中'; // 汉字“中”的Unicode编码是20013

也可以直接用Unicode来表示一个字符,需要加上转义/u;

char n='\u0061';//Unicode中是16进制保存数据的,0061代表的就是97
char n1='\u4e2d';//Unicode中是16进制保存数据的,4e2d代表的就是20013

字符串

与字符char不同的是,字符串是引用类型数据,一个字符串可以存储0个到多个字符,我们用"...."表示。

		String a="";//包含零个字符
		String b="a";//包含一个字符
		String c="abc";//包含三个字符
		String d="abc 789";//包含七个字符,其中一个为空格

因为字符串使用双引号"..."表示开始和结束,那如果字符串本身恰好包含一个"字符怎么表示?例如,"abc"xyz",编译器就无法判断中间的引号究竟是字符串的一部分还是表示字符串结束。这个时候,我们需要借助转义字符\

String s = "abc\"xyz"; // 包含7个字符: a, b, c, ", x, y, z

常见的转义字符包括:

\" 表示字符"
\' 表示字符'
\\ 表示字符\
\n 表示换行符
\r 表示回车符
\t 表示Tab
\u#### 表示一个Unicode编码的字符

字符串的连接
Java的编译器对字符串做了特殊照顾,可以使用+连接任意字符串和其他数据类型,这样极大地方便了字符串的处理。例如:

		String s="hello";
		String s1="world";
		String s2="!";
		String s3=s+s1+s2;

如果用+连接字符串和其他数据类型,会将其他数据类型先自动转型为字符串,再连接:

		int age=23;
		String s="age is ";
		String s3=s+age;

多行字符串
Java 13开始,字符串可以用"""..."""表示多行字符串(Text Blocks)了。举个例子:

String s="""
				我是中国人
				我爱我的祖国\n""";

不可变特性

public class S {

	public static void main(String[] args) {
		String s="hello";
		System.out.println(s);//显示hello
		 s="world";
		System.out.println(s);//显示world
	}

}

空值null
引用类型的变量可以指向一个空值null,它表示不存在,即该变量不指向任何对象。
注意要区分空值null和空字符串"",空字符串是一个有效的字符串对象,它不等于null

数组类型

如果我们有一组相同变量,比如一个小组成员的年龄,代码如下:

public class Group {

	public static void main(String[] args) {
		//五个成员的年龄
		int age1=23;
		int age2=24;
		int age3=26;
		int age4=30;
		int age5=40;
		

	}

}

这样很麻烦,可以引入数组来解决这个麻烦的问题:


public class Group {

	public static void main(String[] args) {
		//五个成员的年龄
		int[] age=new int[5];
		age[0]=23;
		age[1]=24;
		age[2]=26;
		age[3]=30;
		age[4]=40;
		for(int i=0;i<age.length;i++)
		{
			System.out.println(age[i]);
			}

	}

}

定义一个数组,必须使用"类型[]",和单个基本类型变量不同,数组变量初始化必须使用new int[5]表示创建一个可容纳5int元素的数组。

Java的数组有几个特点:

数组所有元素初始化为默认值,整型都是0,浮点型是0.0,布尔型是false
数组一旦创建后,大小就不可改变。
要访问数组中的某一个元素,需要使用索引。数组索引从0开始,例如,5个元素的数组,索引范围是0~4
可以用数组变量.length获取数组大小:


public class Group {

	public static void main(String[] args) {
		//五个成员的年龄
		int[] age=new int[5];
		age[0]=23;
		age[1]=24;
		age[2]=26;
		age[3]=30;
		age[4]=40;
		for(int i=0;i<age.length;i++)
		{
			System.out.println(age[i]);
			System.out.println(age.length);
			}

	}

}

数组是引用类型,在使用索引访问数组元素时,如果索引超出范围,运行时将报错:


public class Group {

	public static void main(String[] args) {
		//五个成员的年龄
		int[] age=new int[5];
		age[0]=23;
		age[1]=24;
		age[2]=26;
		age[3]=30;
		age[4]=40;
		age[5]=50;
		for(int i=0;i<age.length;i++)
		{
			System.out.println(age[i]);
			System.out.println(age.length);
			}

	}

}

也可以在定义数组时直接指定初始化的元素,这样就不必写出数组大小,而是由编译器自动推算数组大小。例如:


public class Group {

	public static void main(String[] args) {
		//五个成员的年龄
		int[] age=new int[]{23,24,26,30,40};
		
		for(int i=0;i<age.length;i++)
		{
			System.out.println(age[i]);
			System.out.println(age.length);
			}

	}

}

可以进一步简写为

int[] age={23,24,26,30,40};

字符串数组:


public class Group {

	public static void main(String[] args) {
		//五个成员的年龄
		
		String []names= {"张三","李四","王五","赵六","武七"};
				for(String b:names)
					System.out.println(b);
	}

}

整数运算

java整数运算规则遵循数学上的四则运算规则,可以使用小括号任意嵌套,如下:


public class Main {

	public static void main(String[] args) {
		int i=1+2;
		int j=9-5;
		int k=6*9;
		int m=36/6;
		int s=(4+5)*(6-3)/3;
		System.out.println(i);
		System.out.println(j);
		System.out.println(k);
		System.out.println(m);
		System.out.println(s);

	}

}

整数的数组不但精确,就连整数运算得到的结果也是精确的,比如除法计算的是整数部分:

		int m=11/2;//结果为5,而不是5.5

使用求余%,求的结果为1:

int m=11%2;//使用求余,求的余数为1

特别注意:整数的除法对于除数为0时运行时将报错,但编译不会报错。
溢出
因为整数的表示范围有限,所以当运算的范围超出了整数的范围,不会报错会出现奇怪的结果,这是由于计算机的存储方式决定的。
还有一种简写的运算符,即+=,-=,*=,/=,它们的使用方法如下:

n += 100; // 3409, 相当于 n = n + 100;
n -= 100; // 3309, 相当于 n = n - 100;

自增自减

Java还提供了++运算和--运算,它们可以对一个整数进行加1和减1的操作:

public class Main {

	public static void main(String[] args) {
		int i=600;
		i=i++;//相当于i=i+1
		i=i--;//相当于i=i-1
		System.out.println(i);
		

	}

}

注意++写在前面和后面计算结果是不同的,++n表示先加1再引用nn++表示先引用n再加1。不建议把++运算混入到常规运算中,容易自己把自己搞懵了。

移位运算

在计算中整数是以二进制存储的,所以可以进行位运算,例如整数8,计算机中是这样存储的 00000000 00000000 00000000 00001000整数是四个字节。可以对整数进行位运算:

public class Main {

	public static void main(String[] args) {
		int n=8;//00000000 00000000 00000000 00001000
		int a=n<<1;//00000000 00000000 00000000 00010000,16
		int b=n<<2;//00000000 00000000 00000000 00100000,32
		int c=n>>1;//00000000 00000000 00000000 00000100,4
		int d=n>>2;//00000000 00000000 00000000 00000010,2
		System.out.println(a);
		System.out.println(b);
		System.out.println(c);
		System.out.println(d);
	}

}

如果对一个负数进行右移,最高位的1不动,结果仍然是一个负数:

int n = -536870912;
int a = n >> 1;  // 11110000 00000000 00000000 00000000 = -268435456
int b = n >> 2;  // 11111000 00000000 00000000 00000000 = -134217728
int c = n >> 28; // 11111111 11111111 11111111 11111110 = -2
int d = n >> 29; // 11111111 11111111 11111111 11111111 = -1

还有一种无符号的右移运算,使用>>>,它的特点是不管符号位,右移后高位总是补0,因此,对一个负数进行>>>右移,它会变成正数,原因是最高位的1变成了0

int n = -536870912;
int a = n >>> 1;  // 01110000 00000000 00000000 00000000 = 1879048192
int b = n >>> 2;  // 00111000 00000000 00000000 00000000 = 939524096
int c = n >>> 29; // 00000000 00000000 00000000 00000111 = 7
int d = n >>> 31; // 00000000 00000000 00000000 00000001 = 1

byteshort类型进行移位时,会首先转换为int再进行位移。

仔细观察可发现,左移实际上就是不断地×2,右移实际上就是不断地÷2

位运算

位运算是按位进行与、或、非和异或的运算。

与运算的规则是,必须两个数同时为1,结果才为1

n = 0 & 0; // 0
n = 0 & 1; // 0
n = 1 & 0; // 0
n = 1 & 1; // 1

或运算规则是,是两个数任意一个数1,结果为1

n = 0 | 0; // 0
n = 0 |1; // 1
n = 1 |0; // 1
n = 1 |1; // 1

非运算的规则是,01互换:

n = ~0; // 1
n = ~1; // 0

异或运算的规则是,如果两个数不同,结果为1,否则为0

n = 0 ^ 0; // 0
n = 0 ^ 1; // 1
n = 1 ^ 0; // 1
n = 1 ^ 1; // 0

运算优先等级
Java的计算表达式中,运算优先级从高到低依次是:

()
! ~ ++ --
  ×   / %-
<< >> >>>
&
|
+= -= *= /=

类型自动提升与强制转型,在运算过程中,如果参与运算的两个数类型不一致,那么计算结果为较大类型的整型。也可以将结果强制转型,即将大范围的整数转型为小范围的整数。强制转型使用(类型),例如,将int强制转型为short

int i = 12345;
short s = (short) i; // 12345

浮点数运算

浮点数运算与整数运算相比只能进行加减乘除的数值运算,不能进行移位运算和位运算。在计算机中虽然浮点数的范围很大,但是浮点数有个特点,就是浮点数通常无法精确表示。
举个栗子:

浮点数0.1在计算机中就无法精确表示,因为十进制的0.1换算成二进制是一个无限循环小数,很显然,无论使用float还是double,都只能存储一个0.1的近似值。但是,0.5这个浮点数又可以精确地表示。
因为浮点数常常无法精确表示,因此,浮点数运算会产生误差:

public class Fc {

	public static void main(String[] args) {
		double x=1.0/10;
		double y=1-9.0/10;
		System.out.println(x);
		System.out.println(y);
//	观察x与y的值是否相同,运算结果表示x=0.1,而y=0.09999998
	}

}

由于浮点数存在运算误差,所以比较两个浮点数是否相等常常会出现错误的结果。正确的比较方法是判断两个浮点数之差的绝对值是否小于一个很小的数:

double r=Math.abs(x-y);
if(r<0.00001)
{	
//两数相等
}
else
{
//两数不相等
}

浮点数在内存的表示方法和整数比更加复杂。Java的浮点数完全遵循IEEE-754标准,这也是绝大多数计算机平台都支持的浮点数标准表示方法。
类型提升
如果参与运算的的数中有一个是整数,可以自动提升为浮点数:

public class Fc {

	public static void main(String[] args) {
		int n=5;
		double x=1.2+24.0/n;//6.0
		System.out.println(x);
		
	}

}

需要特别注意,在一个复杂的四则运算中,两个整数的运算不会出现自动提升的情况。例如:

		int n=5;
		int m=24;
		double x=1.2+m/n;//5.2

溢出
整数运算在除数为0时会报错,而浮点数运算在除数为0时,不会报错,但会返回几个特殊值:

	double x=0.0/0;
		double y =1.0/0.0;
		double z=-1.0/0.0;
		System.out.println(x);//NaN表示Not a Number
		System.out.println(y);//Infinity 表示无穷大
		System.out.println(z);//-Infinity 表示无穷小

可以将浮点数强制转型为整数。在转型时,浮点数的小数部分会被丢掉。如果转型后超过了整型能表示的最大范围,将返回整型的最大值。例如:

int n1 = (int) 12.3; // 12
int n2 = (int) 12.7; // 12
int n2 = (int) -12.7; // -12
int n3 = (int) (12.7 + 0.5); // 13
int n4 = (int) 1.2e20; // 2147483647

如果要进行四舍五入,可以对浮点数加上0.5再强制转型:

ublic class Main {
    public static void main(String[] args) {
        double d = 2.6;
        int n = (int) (d + 0.5);
        System.out.println(n);//n为3
    }
}

布尔运算

对于boolean运算,只有两种结果truefalse
布尔运算是一种关系运算,包括以下几种:
比较运算符:>,>=,<,<=,==,!=
与运算 &&
或运算 ||
非运算 !
关系运算符的优先级从高到低依次是:

!
>>=<<=
==!=
&&
||

短路运算
布尔运算有一个很重要的特性就是短路运算,如果一个运算可以提前确定结果则可以使用短路运算,不再进行后面的运算,直接返回结果。
因为false && x的结果总是false,无论xtrue还是false,因此,与运算在确定第一个值为false后,不再继续计算,而是直接返回false

public class Duanlu {

	public static void main(String[] args) {
		boolean b=5<3;
		boolean result =b&&(5/0>0);
		System.out.println(result);

	}

}

如果没有短路运算,&&后面的表达式会由于除数为0而报错,但实际上该语句并未报错,原因在于与运算是短路运算符,提前计算出了结果false

如果变量b的值为true,则表达式变为true && (5 / 0 > 0)。因为无法进行短路运算,该表达式必定会由于除数为0而报错,可以自行测试。

类似的,对于||运算,只要能确定第一个值为true,后续计算也不再进行,而是直接返回true

boolean result =b||(5>0);//true

三元运算符
Java还提供一个三元运算符b ? x : y,它根据第一个布尔表达式的结果,分别返回后续两个表达式之一的计算结果。示例:

ublic class Main {
    public static void main(String[] args) {
        int n = -100;
        int x = n >= 0 ? n : -n;
        System.out.println(x);
    }
}

上述语句的意思是,判断n >= 0是否成立,如果为true,则返回n,否则返回-n。这实际上是一个求绝对值的表达式。

注意到三元运算b ? x : y会首先计算b,如果btrue,则只计算x,否则,只计算y。此外,xy的类型必须相同,因为返回值不是boolean,而是xy之一。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
embedcpp-2021-03是一个有关嵌入式C++编程的课程,于2021年3月举办。嵌入式C++编程是指在嵌入式系统中使用C++编程语言进行开发的一种方法。 在嵌入式系统中,资源通常是有限的,例如处理器速度、内存容量和存储空间等。因此,使用C++编程语言可以提供更高的灵活性和效率,帮助开发人员充分利用有限的资源。C++在嵌入式系统中的应用范围广泛,例如物联网设备、汽车电子和工业自动化等领域。 embedcpp-2021-03课程旨在向学员介绍嵌入式C++编程的基础知识和技巧。课程内容通常包括以下方面: 1. C++语法和特性:介绍C++的基本语法、面向对象编程和泛型编程等概念,以及C++11、C++14和C++17的一些新特性。 2. 嵌入式系统概述:了解嵌入式系统的基本特点、硬件和软件组成,以及与传统桌面开发的区别。 3. 低级编程:学习如何与硬件交互,包括使用寄存器、配置外设和处理中断等。还可以介绍使用汇编语言优化性能的技巧。 4. 内存管理:探讨嵌入式系统中的内存管理技术,包括堆栈和堆的使用、动态内存分配和对象生命周期管理等。 5. 实时操作系统(RTOS):介绍嵌入式系统中常用的实时操作系统,如FreeRTOS和µC/OS等,学习如何使用RTOS进行任务调度和资源管理。 除了理论知识,embedcpp-2021-03课程通常还包括实际的项目练习,以帮助学员将所学知识应用于实际场景。通过该课程,学员可以了解嵌入式C++编程的基础概念和实践技巧,为嵌入式系统开发提供了一定的基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值