byte

0本来表示一个整数。在C语言中,内存地址也是用整数int表示(32bit)。因此,
(BYTE *)0 表示把整数0强制转换为BYTE型数值的地址

Java的二进制采用补码形式,byte范围是[-128, 127],而Integer.toHexString的参数是int,如果不进行&0xff,那么当一个byte会转换成int时,对于负数,会做位扩展,

举例来说,一个byte类型的-1(即0xff),会被转换成int 类型的-1(即0xffffffff),那么转化出的结果就不是我们想要的了。

-1 hex  : 0xffffffff
-1&0xff : 0xff

-1 bin  : 11111111111111111111111111111111
-1&0xff bin: 11111111

127 bin    : 1111111
-128 bin   : 11111111111111111111111110000000

 

三。将十六进制字符串存为字节数组,可以节省存储空间

0499AFA3432E9F2EBD81C134C1F5E4B3(MD5串)

如果把这个MD5串直接存为字符串,就是32个字节(byte),就是256二进制位。

如果把MD5串的每个字符用16进制字符来表示,那么用二进制位就会表示成4个二进制位,总共是128位,也就是16个字节。那么节省了一半的存储空间。

 

四。在定义int类型的变量时,使用十六进制表示有什么好处?

int a = 0b11000011001111001100011100101000

还是这样好?

1100 0011 0011 1100 1100 0111 0010 1000
int a = 0xC33CC728


 机器可以只有加法而没有减法, 这样计算机运算的设计就更简单了.

1-1 = 1 + (-1) = 0 

于是人们开始探索将符号位参与运算, 并且只保留加法的方法. 首先来看原码:

一、原码

计算十进制的表达式: 1-1=0

1 - 1 = 1 + (-1) = [00000001] + [10000001] = [10000010] = -2

如果用原码表示, 让符号位也参与计算, 显然对于减法来说, 结果是不正确的.这也就是为何计算机内部不使用原码表示一个数.

 

二、反码

为了解决原码做减法的问题, 出现了反码:

正数的反码是其本身

负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.

计算十进制的表达式: 1-1=0

1 - 1 = 1 + (-1) = [0000 0001] + [1000 0001]= [0000 0001] + [1111 1110] = [1111 1111] = [1000 0000] = -0

发现用反码计算减法, 结果的真值部分是正确的. 而唯一的问题其实就出现在"0"这个特殊的数值上. 虽然人们理解上+0和-0是一样的,

但是0带符号是没有任何意义的. 而且会有[0000 0000]和[1000 0000]两个编码表示0.

 

三、补码

正数的补码就是其本身

负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)

于是补码的出现, 解决了0的符号以及两个编码的问题:

1-1 = 1 + (-1) = [0000 0001] + [1000 0001] = [0000 0001] + [1111 1111] = [0000 0000]=[0000 0000]

这样0用[0000 0000]表示, 而以前出现问题的-0则不存在了.  而且可以用[1000 0000]表示-128:

(-1) + (-127) = [1000 0001] + [1111 1111] = [1111 1111] + [1000 0001] = [1000 0000]

-1-127 = -128,  就是[1000 0000]  但是注意因为实际上是使用以前的-0的补码来表示-128,

所以-128并没有原码和反码表示.(对-128的补码表示[1000 0000]补算出来的原码是[0000 0000], 这是不正确的)

使用补码, 不仅仅修复了0的符号以及存在两个编码的问题, 而且还能够多表示一个最低数。

这就是为什么8位二进制, 使用原码或反码表示的范围为[-127, +127], 而使用补码表示的范围为[-128, 127].

 

 四、同余

7 ≡ 7 (mod 12)

(-2) ≡ 10 (mod 12)

7 -2 ≡ 7 + 10 (mod 12)

所谓十六进制String,就是字符串里面的字符都是十六进制形式,因为一个byte是八位,可以用两个十六进制位来表示,因此,byte数组中的每个元素可以转换为两个十六进制形式的char,所以最终的HexString的长度是byte数组长度的两倍.

Byte(字节型)10 - 255


Byte数据类型(字节型)用一个字节(Byte)储存,可区别256个数字,取值范围:0到255。 Byte是从0-255的无符号类型,所以不能表示负数。具体参照数据类型

效果等同于 unsigned char型
typedef unsigned char BYTE
定义一种新类型BYTE,它其实就是unsigned char
在VC++中,byte型数据的定义包含在windows.h头文件中,调用byte需要添加代码#include <windows.h>
而在java中,byte是一个关键字
表示声明了一个整形常量在内容中占用一个字节
取值范围是-128~127


字符串
内存中,如果“ 字符”是以 ANSI编码形式存在的,一个字符可能使用一个字节或多个字节来表示,那么我们称这种字符串为 ANSI字符串或者多字节字符串。如,"中文123" (占8字节,包括一个隐藏的\0)。
字符集
对于ANSI编码方式,存在不同的 字符集(Charset)。同样的字节序列,在不同的 字符集下表示的字符不一样。要正确解析一个ANSI 字符串,还要选择正确的 字符集,否则就可能导致所谓的 乱码现象。不同语言版本的 操作系统,都有一个默认的 字符集。在不指定 字符集的情况下,系统会使用此字符集来解析ANSI字符串。也就是说,如果我们在简体中文版的Windows下打开了一个由日文 操作系统保存的ANSI文本文件(仅包含ANSI 字符串的文本文件),我们看到的将是 乱码。但是,如果我们使用 Visual Studio之类的带编码选择的 文本编辑器打开此文件,并且选择正确的 字符集,我们将可以看到它的原貌。注意:简体中文 字符集中的繁体字和 繁体中文字符集中的繁体字,编码不一定相同(事实证明,似乎是完全不同)。
每个 字符集都有一个唯一的编号,称为 代码页(Code Page)。简体中文(GB2312)的代码页为936,而系统默认 字符集的代码页为0,它表示根据系统的语言设置来选择一个合适的字符集。
Unicode
字符串在 内存中,如果“字符”是以在Unicode中的序号存在的,那么我们称这种字符串为Unicode字符串或者宽字节字符串。在Unicode中,每个 字符都占两个字节。如,"中文123"(占10字节)。
Unicode和ANSI的区别就相当于 输入法内的“ 全角”和“ 半角”的区别。
由于不同ANSI编码所规定的标准是不相同的( 字符集不同),因此,对于一个给定的多字节字符串,我们必须知道它采用的是哪一种字符集则,才能够知道它包含了哪些“字符”。而对于Unicode 字符串来说,不管在什么环境下,它所代表的“字符”内容总是不变的。Unicode 有着统一的标准,它定义了世界上绝大多数的 字符的编码,使得拉丁文、数字、简体中文、繁体中文、日文等都能以同一种编码方式保存。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值