假设我有一个 C 结构,例如:
typedef struct {
UINT8 nRow;
UINT8 nCol;
UINT16 nData; } tempStruct;
有没有办法将结构的所有这 3 个成员放入一个 32 位字中,但仍然能够单独访问它们?
在 s的帮助下的东西union
?
typedef struct {
UINT8 nRow;
UINT8 nCol;
UINT16 nData;
}
tempStruct;
typedef union {
tempStruct myStruct;
UINT32 myWord;
} stuff;
甚至更好(没有“中间”结构):
#include <stdlib.h>
#include <stdio.h>
typedef union {
struct {
int nRow:8;
int nCol:8;
int nData:16;
};
int myWord;
} stuff;
int main(int args, char** argv){
stuff a;
a.myWord=0;
a.nCol=2;
printf("%d\n", a.myWord);
return 0;
}
将其称为 UINT32 怎么样?这不像 C 是类型安全的。
tempStruct t;
t.nRow = 0x01;
t.nCol = 0x02;
t.nData = 0x04;
//put a reference to the struct as a pointer to a UINT32
UINT32* word = (UINT32 *) &t;
printf("%x", *word);
然后,您可以通过取消引用指针来将结构的值作为 32 位字来获取。但是,您的系统的细节可能很重要……如果我在我的机器上运行它,则值为word
0x00040201——也就是说,这些字段的顺序是相反的。如果您尝试将其序列化到另一个系统,我认为不一定会出现这种情况,因此它不可移植。
如果您想将其实际存储为 32 位整数,然后单独引用字段,为什么不
UINT32 word = 0x01020004;
然后在别的地方...
UINT8* row(UINT32 word) {
return (UINT8 *) &word + 3;
}
UINT8* col(UINT32 word) {
return ((UINT8 *) &word) + 2;
}
UINT16* data(UINT32 word) {
return ((UINT16 *) &word);
}
宏将促进可移植的字节序。
typedef struct {
int nRow:8;
int nCol:8;
int nData:16; } tempStruct;
nRow 将只占用 8 位,nCol 将占用 8 位,nDate 将占用 16 位。
这对你有用。
我刚刚写了示例程序来查看它的大小
#include<stdio.h>
typedef struct {
int nRow:8;
int nCol:8;
int nData:16; } tempStruct;
typedef struct {
int nRow;
int nCol;
int nData; } tempStructZ;
int main(void) {
printf("%d\n", sizeof(tempStruct));
printf("%d\n", sizeof(tempStructZ));
return 0;
}
输出:4 16
是的,您可以使用C 中的位域来做到这一点。就像是:
typedef struct {
unsigned nRow : 8;
unsigned nCol : 8;
unsigned nData : 16;
} tempStruct;
如果您还想控制内存布局,您可能需要查看#pragma pack
. 一些编译器为此提供了一个不可移植的选项。