美文网首页
1.变量及运算符

1.变量及运算符

作者: xffish | 来源:发表于2019-04-17 14:13 被阅读0次

1.变量及运算符

基本概念

  • 所有东西都要存在内存才能进一步被使用(请不要抬杠😔)
  • 一般地,这些东西要起名才方便使用
  • 更一般的,名字不能重名,否则将导致歧义
  • 进一步的,有些名字不能起,因为前人已经占用了
  • 内存是宝贵的资源,从计算机诞生到内存白菜价的今天依然适用
  • 所以放在内存里的东西得提前确定好大小以便分配内存空间,系统不会「看心情」多分配
  • Java 已有预定义的基本类型来指定一个东西占的内存大小

由以上可知,要使用一个东西,起码要考虑两个方面:①类型②名字

变量类型

Java是静态强类型的语言,这意味着,在Java的世界里,所有东西都得有确定的类型,并且一经指定,类型再不可更改。比方说你有5个苹果,我可以使用预定义类型int来指定存储的这个 5 的类型或者说指定这个 5 占多大内存;又或者描述圆周率 π,我可以使用预定义类型double来指定存储的这个 3.14159... 的类型或者说指定其占多大内存。

有些其他语言可能是动态类型或者是弱类型,以下附图(看看即可)

常见语言

更完整的类型系统对比表格参见(不看亦可):

https://en.wikipedia.org/wiki/Comparison_of_programming_languages_by_type_system

以下是Java预定义的8个基本类型

分类 名字及内存占用
整数 byte-1字节;short-2字节;int-4字节;long-8字节
浮点数 float-4字节;double-8字节
字符 char-JVM 内部占用2字节
布尔类型 boolean-不探讨占内存大小

最常用的是intdoublecharboolean。另外如果直接把 10、20 这样的字面量常量写在程序里,会认为这是 int类型,如果直接写 3.14 会认为这是double

另外上面提到了「JVM」,这是指「Java 虚拟机」,不展开讲,简单地说 Java 程序无法直接「感知」到物理计算机,因为其实际运行在 JVM 虚拟出的环境中。可以这么认为 JVM 就是 Java 程序的运行环境,Java 程序认为 JVM 就是「真实」的计算机。打个比方,《黑客帝国》中人们生活在 Matrix 虚拟出的世界中,这里的 JVM 可以类比是 Matrix,Java 程序是生活在里面的人。后面再提到的「计算机」、「运行环境」都是指 JVM,不再复述。

名字

如果直接使用 10、20、3.14 这样的数不是不行,但是如果多个地方都要引用该数值,写的就太麻烦了。我们可以起个名字来代指这个数值。如果可以多次更改其值就叫变量,如果赋值一次后再不可更改叫常量,都是字面意思,不解释了。现在先探讨变量,常量到 Java OOP 提到final再说。

Java标识符命名是有规则:

  • 名字必须由字母、数字、下划线 _、美元符号 $ 组成
  • 不能以数字开头
  • 不能和已有变量名重名
  • 不能和特定词即关键字(key word)重名

把握以上 4 点就不会错了。比如以下命名是合法的:abc、ABC123、a_123、_abc、$abc、苹果,而这些是不合法的:2abc、abc#456、xyz abc。最后一个不合法是因为中间有空格。

提一下,这里所称的字母并不单单指英文字母,也包括其他国家语言文字的字符,比如上面的合法示例「苹果」,这正是Java从诞生起就是原生支持多国语言文字特性的优势(😰虽然采用 Unicode-16 有大坑,不再详述)。

但是!推荐起名的做法是

  • 始终以英文字母开头
  • 遵守小驼峰命名法

小驼峰命名法是指如果名字是由多个单词组成的,那么第一个单词首字母小写,从第二个单词起,每个单词的首字母都大写。比如这些:maxGrade、minSalary、writeObject。本教程将始终坚持小驼峰命名法,后不再复述,直到类名采用大驼峰命名法时再提命名规范。

变量声明和使用

上面提到了变量,Java中声明一个变量是简单的,比如下面这样:

int apple = 5;

这是声明了一个int类型的变量,叫 apple,并立即初始化为 5,它占内存 4 字节。所有变量的声明语法都是一样的,先是变量类型,再是变量名字。再看几个例子:

double pi = 3.14159;
char letterA = 'a';
char letterB = '中';
boolean b1 = true;
boolean b2 = false;

其中字符类型的值必须用两个「单引号」包裹住,布尔类型只有两个合法值 true 和 false(🧐虽然 JVM 底层就把 boolean 当成 int,不展开谈)。留意到上述字符类型的值可以为汉字,这也是 Java原生支持多国语言文字的便利。

我们再看看其他的,我们可以对变量做些简单运算,比如

int apple = 5;
apple = apple + 3;

上述代码的意思是把 apple 这个变量的原值 5 拿出来和 3 做加法,然后把结果再赋值给 apple,即是 8。要指出的是第 2 行代码不要看成是数学里面的概念,不能改成如下形式

apple - apple = 3 ==》0 = 3

这也许是初学者一开始不理解的地方,0 怎么会等于 3 了。我要指出的是上述代码不是数学里面的表达式,不能把变量在等号左右变来变去。编程里面,等号的意思是赋值,先计算右边的结果,再赋值给左边。

更多的运算符

可以先看看最常见的「五则运算」

int num = 1 + 2 - 3 * 5 / 5 % 6;

其中加减不必谈,* 是乘法的意思,不能用 X 代替,/ 是除法的意思,不能用 ÷ 代替(你也敲不出这个符号😂),% 是数学里取余(求模)的操作,比如 10÷3=3······1,则10%3的结果就是 1。求模在计算机科学里有重要的作用,这里不展开。按照先乘除后加减的顺序(优先级,后面详细介绍)计算,num 的结果是 0。

算术运算符

顾名思义就是做计算的,一共有 5 个。

意义 符号
加法 +
减法 -
乘法 *
除法或整除 /
取余 %

除了/外,别的运算符很简单,用法已经在上面提到了。而/在不同计算里有不同的含义。

  • 如果左右操作数都是int,那就代表整除。结果是做数学除法后直接舍掉(不是四舍五入)小数部分,比如6/2的结果是 int 类型的 3,而10/3的结果也是 int 类型的 3。
  • 如果左右操作数有一个是浮点数类型,那就是普通的除法,是数学上的结果,有小数位,比如10.0/3 的结果就是 double 类型的 3.33 (具体精度后面再说)

关系运算符

数学上有大于、等于、小于的比较运算符,Java也提供了这些对应的运算符。

意义 符号
大于、大于等于 >、>=
是否相等 ==
小于、小于等于 <、<=
不等于 !=

注意,大于等于不能用数学上的符号 ≥(你也敲不出这个符号😂),小于等于、不等于同理。另外就是判断两个变量是否相等要用连续两个 =,而不是一个 =,请一定要注意这一点,这是初学者最容易犯的错误之一。

关系运算符运算的结果是true或者false

逻辑运算符

数学上有「与」、「或」、「非」的概念,Java也提供了对应运算符。

意义 符号
逻辑与 &&
逻辑或 ||
逻辑非 !

逻辑运算的规则不再繁述。

自增、自减运算符

和 C语言一样,Java也提供了这个快捷的操作。在程序中对变量递增 1 或递减 1 是很常见的运算,此时可以这样写:

int i = 0;
i++; //现在 i 的值是 1
++i; //现在 i 的值是 2

而不用这样写 i = i + 1。上面看到了前缀形式和后缀形式,它们是有区别的。再看例子:

int m = 1,n = 1;
int j = m++; //j 的值是 1,m 变成 2
int k = ++n; //k 的值是 2,n 变成 2

该怎么理解上述代码呢?其实前缀++会先把 n 做自增 1,变成 2,然后把 2 赋值给 k,所以 k 和 n 都是 2;而后缀++会先把 m 的原值赋值给 j,然后 m 再自增 1。如果对代码做反编译会看得更明白,但是不展开。自减是同理,不再举例子。

一般来说前缀形式不会有歧义,先改变变量值再参与运算,最让人迷惑的是后缀。比如:

int a = 5, b = 6;
int c = a++ + b++; // 执行完后 a 的值是 6,b 的值是 7,c 的值是 11

为什么变量 c 是 11?和上面的分析一样,把 a、b的原值拿出来做加法,所以是11,然后 a、b的各自自增 1。但是!实际中不要在一个表达式不要写出两个及以上后缀,就像上面那样,也不要混用前缀和后缀,比如:

int a = 5;
int c = ++a + a++; //有结果,但是这样写是不符合工程规范的,这是考验人的眼睛

还有变量后缀++然后赋值给自己的:

int a = 5;
a = a++; //有结果但不是想的那个结果,这就牵扯到别的问题了

实际中,要么使用i++单独一行的形式,要么最多允许这样a = b + c++,更复杂的形式就不该写了。有前辈这样说

代码是给人看的,只是偶尔在机器上运行

写代码是为了解决问题,不是为了炫技,写正确、简洁的代码不要写有歧义的代码。

复合赋值运算符

有时候为了简洁,把诸如a = a + 3这样的形式写成a += 3+=是复合运算符,在单独写一行不跟别的运算符混合时和前者写法等价,实际中不要写出a+=3+1这样的写法,只允许单独用不可以和别的运算符混合,原因和后缀++一样,为了代码一目了然。「五则运算」都拥有复合形式。

运算符 范例 结果
+= a += b a = a + b
-= a -= b a = a - b
*= a *= b a = a * b
/= a /= b a = a / b
%= a %= b a = a % b

类型转换

前面说过,Java是很看重类型。事实上,一般地,不同类型的数据是不能做运算的,比如:

long a = 3;
int b = a; // 代码错误

第 2 行 b 是int类型,a 是long类型,long占的空间更大,可存储的数字更大,它是不能赋值给较小空间,可存储数字较小的int变量的。但是第 1 行 3 是int类型,怎么就可以赋值给long的变量呢?因为Java允许自动类型转换(也称隐式类型转换),简单说就是不同的类型的数据做运算,运算时以长度最长的类型为主,其他数值自动提升至最长的类型(如上述代码第 1 行),但是反过来不行(如第 2 行)。如果确实类型要向下转换,那得使用专门的语法——强制类型转换(也称显式类型转换),如下所示的圆括号:

double a = 3.14;
int b = (int)a; //b 的值是 3,直接舍掉小数位

一般地,少用强制类型转换,也不要滥用隐式类型转换,最好始终坚持同类型的数据做运算。

运算优先级

运算符优先级有着严格的规定,一个表达式执行顺序是先按运算符优先级,高的(数字越小越高)先执行,同样优先级的,再按结合性的顺序执行。以下见表(看看即可):

优先级 运算符 简介 结合性
1 [ ].( ) 方法调用,属性获取 从左向右
2 !、~、 ++、 -- 一元运算符 从右向左
3 * 、/ 、% 乘、除、取模(余数) 从左向右
4 + 、 - 加减法 从左向右
5 <<、 >>、 >>> 左位移、右位移、无符号右移 从左向右
6 < 、<= 、>、 >=、 instanceof 小于、小于等于、大于、大于等于, 对象类型判断是否属于同类型 从左向右
7 == 、!= 2个值是否相等,2个值是否不等于。 下面有详细的解释 从左向右
8 & 按位与 从左向右
9 ^ 按位异或 从左向右
10 | 按位或 从左向右
11 && 短路与 从左向右
12 || 短路或 从左向右
13 ?: 条件运算符 从右向左
14 =、 += 、-= 、*= 、/=、 %=、 &=、 |=、 ^=、 <、<= 、>、>= 、>>= 混合赋值运算符 从右向左

事实上,不用全部记住这个表格,只需要记住①先乘除后加减;②自增自减比乘除还高;③括号优先级更高,当不清楚先运算那个时就打括号以明确。

其他

  • 要知道浮点数:doublefloat存储可能不准确,从而导致算术运算结果也不准确,一定不能用==来判断两个浮点数是否相同。这不是Java的错,原因不展开,有兴趣可以自行搜索。如果要精确的小数计算,可以使用BigDecimal类来解决,在后面的常见 Java 类使用中再予以介绍。
  • ASCII码。应该予以了解,但篇幅所限,这里不展开,网上有太多的文章。但要记住小写字母 a,大写字母 A 和字符 0 的 ASCII 码,这是 IT 的常识。

还有什么没有谈到

以下内容,有时间或学完了回头再看看,正常学习时可以跳过。

  • 浮点数内部存储结构
  • 浮点数为什么不准确
  • 更多的逻辑运算符
  • 位运算及二进制
  • 逻辑运算规则
  • 逻辑运算存在的「短路」现象
  • 反编译看前缀++和后缀++
  • 数字字面量常量后缀 F 和 L
  • 不同整数类型能表示的最大值是规定的还是计算出来的

相关文章

  • 1.变量及运算符

    1.变量及运算符 基本概念 所有东西都要存在内存才能进一步被使用(请不要抬杠?) 一般地,这些东西要起名才方便使用...

  • Python 3 的运算符及优先级

    Python 支持以下7种运算符 1.算术运算符 假设变量a=10,变量b=5 2.比较运算符 假设变量a为10,...

  • 2020-09-14

    # **一、运算符** ### **1.运算符与变量之间的间隔 :**一元运算符与变量之间没有空格: ``` !b...

  • 2020-09-14

    一、运算符1.运算符与变量之间的间隔 :一元运算符与变量之间没有空格:!bValue~iValue++iCount...

  • iOS代码规范

    运算符 一元运算符与变量之间没有空格 二元运算符与变量之间必须有空格 变量 1.变量名必须使用驼峰格式,自定义类,...

  • 变量的运算符

    运算符:用来连接变量的符号运算符的类型: 1.算数运算符 :+ - * / % 2.关系运算符 :>< >= <=...

  • python学习路线和视频。

    第一阶段 python开发基础和核心特性 1.变量及运算符 2.分支及循环 3.循环及字符串 4.列表及嵌套列表 ...

  • shell 脚本编程快速入门

    变量 特殊变量 变量 变量替换 输入 shell运算符 expr 算术运算符 关系运算 布尔运算符 文件检测运算符...

  • shell 脚本基础 II

    一、Shell 基本运算符 1. 逻辑运算符 变量含义&&逻辑与ll逻辑或 2. 布尔运算符 变量含义!非运算-o...

  • java 基础(一)

    1.运算符 1.1算术运算符 表格中的实例假设整数变量A的值为10,变量B的值为20 1.2位运算符 & | ^其...

网友评论

      本文标题:1.变量及运算符

      本文链接:https://www.haomeiwen.com/subject/vxqnwqtx.html