如何在Java中表示这个?

3
typedef struct _dmk {
       unsigned short int m     : 5;    // 0 - 31  
       unsigned short int d     : 5;    // 0 - 31  
       unsigned short int c     : 1;    // 0 - 1   
       unsigned short int i     : 5;    /* 0 - 31 */
       unsigned short int ip    : 10;   /* 0 - 1024 */
       unsigned short int mj    : 1;    // 0 - 1
       unsigned short int       : 5;    /* unused */ 
       char    msk[10];
    } DMSK;

这里的 ":" 代表什么?我应该使用 byte 数据类型还是 short 数据类型更好?另外,在最后一个 unsigned short int 声明中没有指定变量名。这意味着什么?5、5、1、5 的重要性是什么?请解释一下。谢谢。

2
这是一个位域字段。在Java中没有简单的等价物。 - Paul Tomblin
你可以将它们分为两个 short 或一个 int 并使用移位和掩码来实现。 - Peter Lawrey
许多提供的答案存在问题(基本上都是建议使用下一个最大的整数类型),因为这些位域有两种类型——一种是程序员想要聪明地节省空间而进行的,另一种是因为你需要专门针对硬件中的某些位。而你需要担心的是第二种类型。 - Paul Tomblin
滑动整数类是一个很好的例子。但我只需要为位运算构建它。所以int不是一个好选择。 - JavaBits
6个回答

2

这些是C语言中的位域。这个结构在Java中几乎无法直接表示。你需要编写方法来访问单个位,虽然你可以暴露底层的int。


1

只需要使用Java的方式,比如getM()setM()。当然你需要写它们的代码。

你的结构描述了一个位表。前5位包含字段m,接下来的5位(跨越字节边界)包含d等等。

JFC(Java API)没有可以帮助你的实现,因此如果你经常在程序中使用这样的结构,我建议编写一个类,例如SlidingInteger,它可以处理单个字段。像这样:

class DMK {
    private static final int FIELD_M = 0;
    private static final int FIELD_D = 1;
    private static final int FIELD_C = 2;
    private static final int FIELD_I = 3;
    private static final int FIELD_IP = 4;
    private static final int FIELD_MJ = 5;
    private static final int FIELD_PLACEHOLDER1 = 6;

    private SlidingInteger[] fields;

    public DMK() {
        fields = new SlidingInteger[7];
        fields[FIELD_M] = new SlidingInteger(5);
        fields[FIELD_D] = new SlidingInteger(5);
        fields[FIELD_C] = new SlidingInteger(1);
        fields[FIELD_I] = new SlidingInteger(5);
        fields[FIELD_IP] = new SlidingInteger(10);
        fields[FIELD_MJ] = new SlidingInteger(1);
        fields[FIELD_PLACEHOLDER1] = new SlidingInteger(1);
    }

    public int getM() {
        return fields[FIELD_M].getIntValue();
    }

    public int setM(int newVal) {
        fields[FIELD_M].setIntValue(newVal);
    }

    public int getD() {
        return fields[FIELD_D].getIntValue();
    }

    public int setD(int newVal) {
        fields[FIELD_D].setIntValue(newVal);
    }
}

0

它表示无符号整数所占用的位数。


0
对于m、d、c、i和mj,您可以使用字节(最大8位)数据类型(也可以将c用作布尔值),但ip至少需要一个short(最大16位)。

0
这是一种将数据打包到特定位数的方法,以节省非常小的空间。
您必须使用更大的类型,宽度为8或16位。
没有名称的元素只是显式填充。指定的位数被跳过,在这里并不真正需要,因为下一个元素会按字节对齐。

0

Javolution库中的Class Struct可以满足您的需求(http://www.javolution.org/apidocs/index.html?javolution/io/Struct.html)。请参考“Clock”示例:

 import java.nio.ByteBuffer;
 class Clock extends Struct { // Hardware clock mapped to memory.
     Unsigned16 seconds  = new Unsigned16(5); // unsigned short seconds:5
     Unsigned16 minutes  = new Unsigned16(5); // unsigned short minutes:5
     Unsigned16 hours    = new Unsigned16(4); // unsigned short hours:4
     Clock() {
         setByteBuffer(Clock.nativeBuffer(), 0);
     }
     private static native ByteBuffer nativeBuffer();
 }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接