编程基础与二进制

一、编程基础

函数调用的基本原理:

函数调用中的问题:

1)参数如何传递?

2)函数如何知道返回什么地方?

3)函数结果如何传递给调用方?

解决思路是使用内存来函数调用过程中需要的数据,这种内存叫做栈。栈是一种先进后出的内存,栈底内存地址最高,栈顶最低。

另外,函数返回值一般使用一种特殊的栈--CPU内的存储器来存储。main函数的相关数据放在栈底,每调用一次函数,都会将函数

的相关数据入栈,调用结束就出栈。举个例子:

public class Sum {

    public static int sum(int a, int b) {
int c = a + b;
return c;
} public static void main(String[] args) {
int d = Sum.sum(1, 2);
System.out.println(d);
}
}

1.调用Sum.sum()方法前栈的情况:

2.在程序执行到sum()函数内部,返回前,栈的情况:

函数的参数和函数内定义的变量,都分配在栈中,这些变量在函数被调用的时候才分配,

而且在调用结束后就被释放了,但这种说法主要针对基本数据类型。

数组和对象的内存分配:

public class ArrayMax {
public static int max(int min, int[] arr) {
int max = min;
for(int a : arr) {
if (a > max) {
max = a;
}
}
return max;
}
public static void main(String[] args) {
int[] arr = new int[]{2, 3, 4};
int ret = max(0, arr);
System.out.println(ret);
}
}

在程序执行到max函数调用return语句之前:

当main函数执行结束,栈空间没有变量指向堆中的内容时,Java系统会自动进行垃圾回收,释放该空间。

二、理解数据背后的二进制

整数的二进制表示:

二进制使用最高位表示符号位,用1表示负数,用0表示正数。但哪个高位?

整数有4种类型byte,short,int,long分别占用1,2,4,8个字节,即分别占用

8,16,32,64位,每种类型的符号位都是最左边的那一位。

但是,负数的表示不是简单的把最高位变为1。而是使用补码表示法来表示。

补码:就是在原码的基础上取反然后加上1。例如:

1)-1:1的原码是0000 0001,取反为1111 1110再加上1后是1111 1111。

2)-2:2的原码是0000 0010,取反为1111 1101再加上1后是1111 1110。

3)-127:127的原码是0111 1111 ,取反为1000 0000再加上1后是1000 0001。

给定一个负数的二进制表示,想要知道它的十进制值,可以采用相同的补码运算。

比如-2,原码为1111 1110,取反为0000 0001,再加上1,得到0000 0010,就是

十进制的2。

思考:为什么会采用补码再加1这种奇怪的方式表示负数?(提示:计算机只能做加法)。

整数的十六进制表示:

为什么要使用十六进制?因为二进制写出来一长串啊,弟弟。

用法:可以使用十六进制直接写数字常量,在数字前加0x就行了。10到15用A到F表示。

注意:Java7以后也可以使用二进制数字常量,在数字前面加0b或者0B就行了。

位运算

1.移位:

1)左移:操作符为<<,向左移动,右边低位补0,高位舍弃。左移1位,相当于该数十进制乘以2(同时适用于正数和负数)。

2)无符号右移:操作符>>>,向右边动,右边舍弃掉,左边补0,相当于十进制除以2(仅适用于正数)。

3)有符号右移:操作符>>,向右边动,右边舍弃掉,左边补什么取决于原来最高位是什么,原来

是1就补1,原来是0就补0,右移1位相当于除以2(适用于正负数)。

2.按位与---&:

先将两个数据转化为二进制数,然后按位进行与运算,同为1结果为1,其它情况结果为0

用途:

1)清零

2)取一个数种的指定位

3)判断奇偶性:任意数与1取位与,结果1的为奇数

3.按位或-----|

先将两个数据转化为二进制数,然后进行按位或运算,只要有一个是1结果为1,不然结果为0;

用途:

4.按位异或----^ 

先将两个数据转化为二进制数,然后进行按位异或运算,只要位不同结果为1,不然结果为0

用途:

二进制、十进制与十六进制之间的转换

1)二进制转十进制

1010 = 0*2+ 1*21 + 0*22 + 1*23

2)二进制转十六进制

从左到右4个数为一个单位,不足4位补0:

0010 1100 ----> 2 22+2----> 2C

3)十进制转二进制

除以2取余法:

123  -----  1

61   -----  1

30   -----  0

15   -----  1

7    -----  1

3    -----  1

1    -----  1

0

结果为: 11 1101

4)十进制转十六进制

除16取余法:

188

11 ---- 12

0  ---- 11

AB

5)十六进制转二进制

十六进制数通过除2取余法,得到二进制数,对每个十六进制为4个二进制,不足时在最左边补零。

6)十六进制转十进制

AB =  11*161 + 12*160

小数的二进制表示:

小数计算为什么会出错?

实际上,不是运算本身会出错而是计算机根本就没办法精确地表示很多数。

比如0.1,其实这跟十进制不能精确表示1/3是一个道理。二进制只能表示

那些可以表述为2的多次方和的数。

字符的编码与乱码:

编码有两大类:一是非Unicode编码,一类是Unicode编码。

非Unicode编码:

1)ASCII:规定了0~127的每个数字代表的意义。

2)其他:ISO 8859-1,Windows-1252,GB2312,GBK,GB18030,Big5

其中ASCII是基础,其他编码方式兼容ASCII。

Unicode编码:

Unicode主要做了一件事,就是给世界上所有字符分配了唯一的数字编号。

但是要注意,它并没有规定这些数字编号怎么对应到具体的二进制表示,这与其他的编码不同,

具体怎么对应是由UTF-32,UTF-16,UTF-8这几种编码方案确定的。具体对应方式:

1)UTF-32:字符编号的整数二进制形式,4个字节。缺点:浪费空间。

2)UTF-16:常用字符集用两个字节表示,增补字符集用4个字节表示。

3)UTF-8:使用变长字节表示,每个字符使用的字节个数与其Unicode编号相关,字节数1-4个不等(小于128的与ASCII一样)。

乱码的原因:

1)解析错误

2)在解析错误的基础上进行了编码转换

char的真正含义:

在Java内部进行字符处理时,采用的是UTF-16BE。

char本质上是一个固定占用两个字节的无符号正整数,这个正整数对应Unicode编号,

用于表示那个Unicode编号表示的字符。char的赋值方式:

char a = 'A';
char b = '唐';
char c = 23235;
char d = 0x66;
char e = '\u9a6c';

直接写字符常量的时候应该注意文件的编码,比如,GBK编码的源码文件

按UTF-8打开,字符会变成乱码,赋值的时候是按照当前的编码解读方式

,将这个字符形式对应的Unicode编号赋值给变量。

Java笔记(一)编程基础与二进制的更多相关文章

  1. [Java入门笔记] 面向对象编程基础(二):方法详解

    什么是方法? 简介 在上一篇的blog中,我们知道了方法是类中的一个组成部分,是类或对象的行为特征的抽象. 无论是从语法和功能上来看,方法都有点类似与函数.但是,方法与传统的函数还是有着不同之处: 在 ...

  2. Java高并发编程基础三大利器之CountDownLatch

    引言 上一篇文章我们介绍了AQS的信号量Semaphore<Java高并发编程基础三大利器之Semaphore>,接下来应该轮到CountDownLatch了. 什么是CountDownL ...

  3. Java笔记 - Socket编程

    两个Java应用程序可以通过一个双向的网络通讯连接实现数据交换,这个双向链路的一端称为一个Socket.java.net包中定义的两个类Socket和ServerSocket,分别用来实现双向链路的c ...

  4. Python笔记002-Python编程基础概念

    第二章(1):Python编程基础概念 1. Python 程序的构成 Python 程序有模块组成.一个模块对应 Python 源文件,一般后缀名是:.py. 模块有语句组成.运行 Python程序 ...

  5. [Java入门笔记] 面向对象编程基础(一):类和对象

    什么是面向对象编程? 我们先来看看几个概念: 面向过程程序设计 面向过程,是根据事情发展的步骤,按进行的顺序过程划分,面向过程其实是最为实际的一种思考方式,可以说面向过程是一种基础的方法,它考虑的是实 ...

  6. Java精选笔记_Java编程基础

    Java的基本语法 Java代码的基本格式 修饰符 class 类名 {   程序代码 } 一个Java源文件只定义一个类,不同的类使用不同的源文件定义:将每个源文件中单独定义的类都定义成public ...

  7. [Java入门笔记] 面向对象编程基础(三):成员变量和局部变量

    在类中,变量根据定义的位置不同,可以分为成员变量和局部变量.

  8. 《Java编程的逻辑》第一部分 编程基础与二进制

  9. shell学习笔记1---shell编程基础

    Shell是什么? Shell 是一个应用程序,它连接了用户和 Linux 内核,让用户能够更加高效.安全.低成本地使用 Linux 内核,这就是 Shell 的本质. Shell 本身并不是内核的一 ...

随机推荐

  1. 编程语言,执行python程序,变量(命名规范)

    编程语言 分类: ​ 计算语言/汇编语言/高级语言 计算语言: ​ 站在计算机的角度,说计算机能听懂的语言,就是直接用二进制编程,直接操作硬件 优点是最底层,执行速度最快 缺点是最复杂,开发效率最低 ...

  2. 美国主机BlueHost vs HostEase

    网站备案对于大部分个人站长而言,花费成本高.程序复杂,因此在挑选主机时,常选择免备案IDC服务商,如美国.香港主机,且前几日国内某免备案机房因个别网站涉及非法言论而配合相关部门采取停网整顿等,为此站长 ...

  3. 使用python解决算法和数据结构--使用栈实现进制转换

    可以将10进制数据转换成2进制,8进制,16进制等. 晚上练练算法和数据结构哈. # coding = utf-8 class Stack: def __init__(self): self.item ...

  4. es6 箭头函数【箭头表达式】

    箭头函数,通过 => 语法实现的函数简写形式,C#/JAVA8/CoffeeScript 中都有类似语法.与函数不同,箭头函数与其执行下文环境共享同一个 this.如果一个箭头函数出现在一个函数 ...

  5. es6 新增字符串方法

    es6新增了4个字符串处理的方法:startsWith,endsWith,includes,repeat. 1.简单使用 includes()返回布尔值,表示是否找到了参数字符串 startsWith ...

  6. A - Points and Segments CodeForces - 429E

    题解: 方法非常巧妙的一道题 首先考虑要求全部为0怎么做 发现是个欧拉回路的问题(很巧妙) 直接dfs一遍就可以了 而这道题 要求是-1,1,0 我们可以先离散化 完了之后判断每个点被奇数还是偶数条边 ...

  7. 0day漏洞

    0Day的概念最早用于软件和游戏破解,属于非盈利性和非商业化的组织行为,其基本内涵是“即时性”. Warez被许多人误认为是一个最大的软件破解组 织,而实际上,Warez如黑客一样,只是一种行为. 0 ...

  8. php json_encode转换中文乱码

    $arr = ["a"=>'范德萨似懂非懂']; echo json_encode($arr,JSON_UNESCAPED_UNICODE);

  9. BZOJ2821 作诗(Poetize) 主席树 bitset

    原文链接https://www.lydsy.com/JudgeOnline/problem.php?id=2821 题目传送门 - BZOJ2821 题意 $n$ 个数,$m$ 组询问,每次问 $[l ...

  10. RocketMQ事务消息回查设计方案

    用户U1从A银行系统转账给B银行系统的用户U2的处理过程如下:第一步:A银行系统生成一条转账消息,以事务消息的方式写入RocketMQ,此时B银行系统不可见这条消息(Prepare阶段) 第二步:写入 ...