Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go:位字段和位打包_Go_Bit Fields - Fatal编程技术网

Go:位字段和位打包

Go:位字段和位打包,go,bit-fields,Go,Bit Fields,C语言的位字段提供了一种在结构中定义任意宽度字段的相当方便的方法(暂时不考虑可移植性问题)。例如,下面是一个简单的结构,其中包含两个字段和一个“标志”: #pragma pack(push,1) struct my_chunk{ unsigned short fieldA: 16; unsigned short fieldB: 15; unsigned short fieldC: 1; }; #pragma pop() 添加#pragma语句将此结构打包成一个32位

C语言的位字段提供了一种在结构中定义任意宽度字段的相当方便的方法(暂时不考虑可移植性问题)。例如,下面是一个简单的结构,其中包含两个字段和一个“标志”:

#pragma pack(push,1)
struct my_chunk{

    unsigned short fieldA: 16;
    unsigned short fieldB: 15;
    unsigned short fieldC:  1;
};
#pragma pop()
添加#pragma语句将此结构打包成一个32位字(例如,确保
my_chunk
指针的指针操作对齐,同时节省空间)

访问每个字段在语法上都非常好:

struct my_chunk aChunk;
aChunk.fieldA = 3;
aChunk.fieldB = 2;
aChunk.fieldC = 1;
在没有语言帮助的情况下执行此操作的另一种方法相当难看,而且几乎都要由汇编程序来完成。e、 g.一种解决方案是为每个要访问的字段设置bitshift宏:

#define FIELD_A  0xFF00
#define FIELD_B  0x00FE
#define FIELD_C  0x0001

#define get_field(p, f) ((*p)&f)
#define set_field(p, f, v) (*p) = (v<<f) + (*p)&(~f)

...
set_field(&my_chunk, FIELD_A, 12345);
#定义字段A 0xFF00
#定义字段_B 0x00FE
#定义字段_C 0x0001
#定义get_字段(p,f)((*p)和f)
#定义集合域(p,f,v)(*p)=(v


您可以编写一个Go包来完成此操作;不需要汇编程序。

如果目标只是拥有一个非常小的结构,您可能只需要执行以下操作:

package main

import "fmt"

type my_chunk uint32

func (c my_chunk) A() uint16 {
  return uint16((c & 0xffff0000) >> 16) 
}

func (c *my_chunk) SetA(a uint16) {
  v := uint32(*c)
  *c = my_chunk((v & 0xffff) | (uint32(a) << 16))
}

func main() {
  x := my_chunk(123)
  x.SetA(12)
  fmt.Println(x.A())
}
主程序包
输入“fmt”
键入my_chunk uint32
func(c my_chunk)A()uint16{
返回uint16((c&0xffff0000)>>16)
}
func(c*my_chunk)SetA(a uint16){
v:=uint32(*c)

*c=my_chunk((v&0xffff)|(uint32(a)只是一个附录:我尝试用一个带有uint16和uint32的结构(而不仅仅是一个“chunk”变量)来实现这一点,不幸的是go给出了Sizeof()=8,而不是结构的6。除此之外,一个大的(迟来的)感谢您的回答,这非常有帮助是的,对于结构,成员可能是单词对齐的。如果您已经使用了“不安全”,您可以使用[3]uint16并获得带有“(*uint32)(不安全的.指针(&val[1])”的uint32部分,这避免了打包/解包的成本,但有点难看。请注意,他并不是说必须使用assembler,而是说当您必须手动访问这些子字段时,它看起来像assembler,具有所有所需的屏蔽/移位。