2017-05-23 54 views
1

保留的内存位置我有一个结构:如何编写为结构

struct foo{ 
    uint8_t i1 : 4; 
    uint8_t i2 : 4; 
    uint8_t i3 : 4; 
    uint8_t i4 : 4; 
} 

现在,我有一个16位整数(叫它),我想写的内存位置,对于这个结构,而不必这样做:

foo1.i1 = (uint8_t)a>>12; 
foo1.i2 = (uint8_t)a>>8; 
foo1.i3 = (uint8_t)a>>4; 
foo1.i4 = (uint8_t)a; 

是否有一个选项可以将16位写入foo1的内存位置。喜欢的东西:

*(*uint16_t)&foo1 = a; 
+1

第一个问题:你为什么要使用位域? –

+2

体面的编译器意识到你在做什么 - 这可能是过早的优化。当然,如果编译器反转布局(字节中的位顺序未指定),那么您的投射就是错误的。 – MSalters

+0

@Neil使用位域有什么问题? –

回答

2

首先,你应该确保这是你需要做的优化 - 操作不当,你可能会遇到关于对齐,字节顺序等。这样的问题,你我们希望使用分析器来检查代码的性能,并确定这是否会消耗大量处理器时间。记住what Donald Knuth wrote

程序员浪费大量的时间思考,也不必担心,他们的节目非关键部分的速度,而这些尝试的效率居然有当调试和维护被认为是一个强烈的负面影响。我们应该忘记小效率,大约97%的时间:过早优化是所有邪恶的根源。但我们不应该在这个关键的3%中放弃我们的机会。

一旦您确认这是一个有用的优化,那么您应该可以通过几种方式来完成。其中之一是使用memcpy ...

memcpy(&foo1, &a, sizeof(foo1)); 

或者,你可以做一个foo1unionuint16_t成员和写入...

union { 
    struct foo f; 
    uint16_t u; 
} foo1; 
foo1.u = a; 
+2

请注意,通过C++中的联合进行类型双击是未定义的行为。 – NathanOliver

+0

@NathanOliver这是真的,但它不仅仅是'union'方法的问题 - 基本上任何涉及“我将忽略这些对象的C++类型并将它们当作原始内存”的任何事情都会有类似的可移植性问题(因此,为什么你应该更喜欢便携式,非优化版本,除非你有充分的理由相信手工优化它会产生有意义的差异)。 –

+0

添加注释,我们应该使用分析器来衡量*最重要的瓶颈*;这些是我们在优化程序时应该瞄准的目标,这意味着我们需要*一个实际的解决方案*来优化...然后,一旦我们应用了优化,我们应该再次重新分析*以确保我们实际进行了优化。任何其他方法仅仅是* guesswork *,* guesswork *会导致*较慢的代码! – Sebivor