如何获得结构中任何成员的位位置
如何获得结构中任何成员的位位置?如何获得结构中任何成员的位位置
在示例>
typedef struct BitExamStruct_
{
unsigned int v1: 3;
unsigned int v2: 4;
unsigned int v3: 5;
unsigned int v4: 6;
} BitExamStruct;
是否有任何宏观得到任何成员一样GetBitPos(V2,BitExamStruct)位的位置?
我认为编译器可能会根据结构中的位长知道成员的位置。所以我想知道我是否可以通过使用一个简单的宏而不运行代码来获得它。
预先感谢您。
我不知道这样做的标准方式,但这并不意味着您找不到解决方案。
以下不是有史以来最漂亮的代码;这是一种黑客来识别变量在内存中的“开始”的位置。请记住以下能给取决于字节顺序不同的结果:
#include <stdio.h>
#include <string.h>
typedef struct s_toto
{
int a:2;
int b:3;
int c:3;
} t_toto;
int
main()
{
t_toto toto;
unsigned char *c;
int bytes;
int bits;
memset(&toto, 0, sizeof(t_toto));
toto.c = 1;
c = (unsigned char *)&toto;
for (bytes = 0; bytes < (int)sizeof(t_toto); bytes++)
{
if (*c)
break;
}
for (bits = 0; bits < 8; bits++)
{
if (*c & 0b10000000)
break;
*c = (*c << 1);
}
printf("position (bytes=%d, bits=%d): %d\n", bytes, bits, (bytes * 8) + bits);
return 0;
}
我要做的是,我的整个结构初始化为0,我设置1,因为我想找到的变量的值。结果是结构中只有一位被设置为1。然后我读取每个字节的内存字节,直到找到一个不是零的字节。一旦找到,我可以看看它的位,直到找到所设置的位。
有趣。 '0b10000000'表示法是C中的一个非标准扩展(虽然C++已经对其进行了标准化)。更重要的是,你必须有'toto.c'引用来完成这项工作,这意味着你不能一般地完成这项工作。你的代码适用于'toto.c';必须修改以设置“toto.b”或“toto.a”。但它总比没有好,这是标准提供的替代方案。位字段是标准C最神秘的部分之一,几乎所有行为都是实现定义的。 –
'(bytes * 8)+ bits'是一个小端字节,大端位索引。我喜欢一点一点的一致的endian编号。奖金'0b10000000' - >'1' – chux
没有便携式(又名标准C)的方式。但是,如果你需要完全控制,或者需要这些信息,那么位域是错误的。正确的解决方案是转移和屏蔽。当然这只有在你控制源代码的时候才是可行的。
感谢您的评论。该工具生成我公司硬件寄存器的头文件。通常,我为位域定义我真正需要的位位置。但每次硬件注册规格。发生了变化。 –
然后你可能不关心可移植性,你可能能够在你的编译器ABI文档中找到这些信息。 –
我有点困惑于成员变量的命名。比特1,...,比特4应该是正好1比特的大小,还是比特1应该是3比特的大小,比特2的大小是4比特,比特3的大小是5比特,比特4的大小是6比特? – rwols
抱歉让人困惑。它只是一个名字。位1有3位,位2有4位。类似的东西。我改变了会员的名字。 –
然后我相信[offsetof](http://en.cppreference.com/w/c/types/offsetof)就是你要找的东西。 – rwols