如何使指针类对象指向数组的中间

问题描述 投票:0回答:2

我有一个字节缓冲区,并希望有指向第一个元素的标识符,该元素不必是数组本身的第一个元素。

     private void uint32ToBuffer(int val, byte[] buffer)
    {
        buffer[0] = (byte)val;
        buffer[1] = (byte)(val >>> 8);
        buffer[2] = (byte)(val >>> 16);
        buffer[3] = (byte)(val >>> 24);
    }

我想做

byte[] buffer = new byte[512];
uint32ToBuffer(3, &buffer[2]);

但显然它不起作用。是否有可能在不让函数

uint32ToBuffer
知道它应该写入数组的初始位置以从
C
类似语言复制指针算术逻辑的情况下以某种方式执行此操作?

java arrays pointers
2个回答
0
投票

没有。

您有几个选择:

使用
java.nio.buffer.ByteBuffer

ByteBuffer是一个抽象的概念;它们很像数组,因为它们是固定大小并代表字节。与

byte[]
不同,它有一个有意义的 API,与
byte[]
不同,它已经在跟踪中烘焙(例如,它有一个“位置”,不像字节数组只有一个长度)。事实上,非常棒的跟踪,带有标记、重置和限制。实际上,字节缓冲区由“围绕包含数据的数组的轻型对象包装器”或“直接访问内存映射 I/O 事物”组成。

事实上,ByteBuffer 已经具有 write-int-to-byte-array-as-little-endian 功能!

byte[] buffer = new byte[512];
ByteBuffer bb = ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN);
bb.position(2);
bb.putInt(3);

此时不再需要

uint32ToBuffer
方法; bytebuffer 已经有了它。
putInt(3)
电话:

  • 将'3'作为32位整数写入位置
    [2]
    [3]
    [4]
    [5]
    的字节中(因为bb的位置是'2';它是相对写入)。具体写成3/0/0/0是因为buffer对象的字节序是
    LITTLE_ENDIAN
    。默认情况下,它们是大端字节序,并且会写入 0/0/0/3。不知道你为什么要小端,这是一个非常过时的概念,只有 x86/x64 芯片仍在使用它:互联网往往是大端,而此时更受欢迎的 ARM 芯片也.如果您正在设计协议,我强烈建议您改写为大端。
  • 将 bb 的位置提升到 6.

还有绝对写法:

bb.putInt(2, 3);

这具有相同的效果(将

3
写入
buffer[2]
,并将
0
写入
buffer[3]
buffer[5]
),但不依赖于缓冲区的位置值,也不对其进行修改。

我强烈建议您在这里使用它,对于您正在做的所有其他涉及“将小端字节序写入字节数组”的操作。 ByteBuffer API 可能包含您目前正在为其编写的实用方法的所有内容

传递一下

或者,传递位置;这在 Java API 中非常常见:

private void uint32ToBuffer(int val, byte[] buffer, int pos) {
    buffer[pos] = (byte)val;
    buffer[pos + 1] = (byte)(val >>> 8);
    buffer[pos + 2] = (byte)(val >>> 16);
    buffer[pos + 3] = (byte)(val >>> 24);
}

// ... and if you want, for convenience:
private void uint32ToBuffer(int val, byte[] buffer) {
  uint32ToBuffer(val, buffer, 0);
}

Java 中没有办法创建作为其他数组的子切片的数组; array 非常基础,完全不支持任何可能算作“花哨”的东西。 Java 也没有任何类型的指针算法,因此,将 2 个插槽指向字节数组的引用根本不是问题。在 C 语言中,字节数组本质上“只是一个指针”,你不知道它有多长。在 java 中,因为缓冲区溢出是一个相当普遍的安全问题,所以这个概念不以任何方式存在,这是故意的。字节数组确实是它们自己的数据结构,特别是知道它们实际上是一个字节数组,以及它们有多长。 Java 使得不可能(除非你写一些被黑的类文件 禁用 JVM 的类验证器)来编程缓冲区溢出问题。为此,指针 cannot 以这种方式修改(您不能在 java 中将指针“加 2”)。


0
投票

只需使用 ByteBuffer 类及其支持方法。

  • 分配
    ByteBuffer
  • 并传递添加数据的位置。索引会自动增加。
ByteBuffer b = ByteBuffer.allocate(10);
 uint32ToBuffer(3, b.position(2));
 System.out.println(Arrays.toString(b.array()));

版画

[0, 0, 3, 0, 0, 0, 0, 0, 0, 0]

方法

private static void uint32ToBuffer(int val, ByteBuffer buffer){
     buffer.put((byte)val);
     buffer.put((byte)(val >>> 8));
     buffer.put((byte)(val >>> 16));
     buffer.put((byte)(val >>> 24));
 };
© www.soinside.com 2019 - 2024. All rights reserved.