摘要:这个就有意思了我们发现我们如果换一种书写方式可以更直观理解数组在内存中模样事件起因前些天阅读一本相关书籍的时候看到这么一段话显而易见上述寥寥代码的主要内容是在阐述仅仅作为视图读写内存的道理和公用了同一段内存而我今天想说这里有一个很有意思的事
这个就有意思了, 我们发现, 我们如果换一种书写方式, 可以更直观理解数组在内存中模样.
事件起因前些天阅读一本js 相关书籍的时候, 看到这么一段话.
var buffer = new ArrayBuffer(12); var x1 = new Int32Array(buffer); x1[0] = 1; var x2 = new UInt8Array(buffer); x2[0] = 2; x1[0] // 2
显而易见, 上述寥寥代码的主要内容是在阐述 TypedArray仅仅作为 ArrayBuffer 视图读写内存的道理. x1和x2公用了同一段内存._
而我今天想说这里有一个很有意思的事情.
字节序大家公认的概念, 也是计算机基础理论知识的一部分.
内存中使用8个二进制位(bit)表示一个字节(Byte).
UInt8 是使用一个字节表示的无符号整数
UInt32 则是使用了4个字节表示的无符号整数
我们使用无符号整数这样简单的数据结构, 来看看刚刚的赋值过程做了什么.
x1[0] = 1
我们知道, x1是一个 Int32视图, 所以第一个元素的长度是四个字节. 也就是说, 该部分的值是 0x000001.
高位 | 低位 | ||
---|---|---|---|
00 | 00 | 00 | 01 |
x2[0] = 2
我们知道, x2是一个 Int8视图, 所有第一个元素的长度是一个字节, 也就是说, 该部分的值是 0x02.
瞧, 现在 x1[0] 应该变成什么样?
是 0x00000002 ?
高位 | 低位 | ||
---|---|---|---|
00 | 00 | 00 | 02 |
还是 0x02000001 ?
高位 | 低位 | ||
---|---|---|---|
02 | 00 | 00 | 01 |
这个问题的本质, 即 __内存中, Int32数据类型内部的四个字节, 是低位在前, 还是高位在前?__.
如果是高位在前, 则x2[0]指向的是 x1[0]最高位的字节. 反之, 则是指向的最低位.
关于字节序, 在计算机的世界里有这样一种定义和区分. 大端序/小端序.
详细设定我们参考 (wiki)[https://zh.wikipedia.org/wiki... 就好.
我们绝大多数时候再现代计算机上使用的字节, 都是小端序.
而网络传输中使用的是大端序, 如 IP 报头
瞧, 书写一个数组试试.假设我们有一个 UInt16Array(3)
var x3 = new UInt16Array([11, 22, 33]);
我们在草稿纸上会这么写
x3[0] | x3[1] | x3[2] |
---|---|---|
11 | 22 | 33 |
也就是说我们习惯性把第一元素写在左边. 换成十六进制的写法就是
0x000B | 0x0016 | 0x0021 |
---|
如果现在没看出来为什么我想说从左到右书写数组会造成有趣的误解, 那我再试着用二进制方式把这个数组写出来 :)
00000000 00001011 | 00000000 00010000 | 00000000 00100001 |
---|
注意,最左边一个格子是 x3[0] 哦! 这时候, 我们试着使用x2这样的 UInt8Array 视图来解读这个数组.
正确的解读应该是
00001011 | 00000000 | 00010000 | 00000000 | 00100001 | 00000000 |
---|---|---|---|---|---|
0x0B | 0x00 | 0x16 | 0x00 | 0x21 | 0x00 |
11 | 0 | 22 | 0 | 33 | 0 |
而不是
00000000 | 00001011 | 00000000 | 00010000 | 00000000 | 00100001 |
---|---|---|---|---|---|
0x00 | 0x0B | 0x00 | 0x16 | 0x00 | 0x21 |
0 | 11 | 0 | 22 | 0 | 33 |
因为, 小端字节序的设计中, __低位在前__.
所以, 如果我们一开始就在脑海中将所构思的数组从右往左书写
x3[2] | x3[1] | x3[0] |
---|---|---|
33 | 22 | 11 |
0x0021 | 0x0016 | 0x000B |
00000000 00100001 | 00000000 00010000 | 00000000 00001011 |
改变数据类型去解读的结果则是
x2[5] | x2[4] | x2[3] | x2[2] | x2[1] | x2[0] |
---|---|---|---|---|---|
00000000 | 00100001 | 00000000 | 00010000 | 00000000 | 00001011 |
0x00 | 0x21 | 0x00 | 0x16 | 0x00 | 0x0B |
0 | 33 | 0 | 22 | 0 | 11 |
看! 完全不会有交换字节带来的误解!
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/84704.html
摘要:是一种强类型语言,因此,定义了基本数据类型。运算符先从运算符谈起。基本数据类的基本数据类型同其它高级程序语言比较类似。常用类类型除了一些基本数据类型,提供的一些类类型,使用频率也很高。 Java 是一种强类型语言,因此,Java 定义了基本数据类型。同时, Java 和其它高级计算机语言一样,有多种运算符,这在我们编程过程中极为有用。 运算符 先从运算符谈起。 顾名思义,运算符解决的是...
摘要:题目要求假设有一共个数字,从左往右开始每隔一位删除一个数字,到达最右侧后,再从右往左每隔一位删除一个数字,如此反复,直到剩下最后一个数字。由此可见,假如我们定义一个递归函数我们可以有来获取结果。 题目要求 There is a list of sorted integers from 1 to n. Starting from left to right, remove the fir...
摘要:文档地址中文文档英文文档源码地址第一个函数是,不过源码中依赖了,所以第一篇文章就从开始。这个函数的作用就是裁剪数组,从下标开始,到下标结束,但是并不包含,并将结果作为一个数组返回。并且注明了这个方法用于代替来确保数组正确返回。 百忙之中(闲来无事)想抽点时间好好读一下源码,于是就选了Lodash来写一个系列罢。读源码顺序就按照loadsh文档顺序来。 文档地址:中文文档 英文文档源...
摘要:狭义的对象字面量形式是中我最喜欢的一种结构,因为其灵活。今天准备介绍中对象的扩展相关的知识点,由于煲剧晚了,先写一半,剩下的下次再介绍。 狭义的对象字面量形式是JavaScript中我最喜欢的一种结构,因为其灵活。今天准备介绍ES6中对象的扩展相关的知识点,由于煲剧晚了,先写一半,剩下的下次再介绍。 主要知识点: 对象属性的简写 动态 · 属性名 Object.is(value1,...
阅读 2020·2021-11-15 11:38
阅读 2052·2019-08-30 15:55
阅读 2186·2019-08-30 15:52
阅读 3171·2019-08-30 14:01
阅读 2688·2019-08-30 12:47
阅读 1134·2019-08-29 13:17
阅读 1066·2019-08-26 13:55
阅读 2635·2019-08-26 13:46