我目前正在参与一个基于C语言的嵌入式项目,其中我们有以下组件控制逻辑:
当前代码对我来说看起来非常清晰和可读,当所有您拥有的是两个具有两个不同值的变量时-我不会为您建议的替代方案更改它,它看起来非常好。如果有的话,也许可以使用查找表。
static const int input_output_table[2][2] = {
[OFF][OFF] = NO_MOVEMENT,
[OFF][ ON] = DIRECTION_B,
[ ON][OFF] = DIRECTION_A,
[ ON][ON] = ERROR
};
output = input_output_table[input1][input2];
(如果需要确保input1/input2可以是0或1以外的值,请执行任何完整性检查。或者将它们强制为布尔值,如output = input_output_table[!!input1][!!input2];
如果重写它的原因是性能,那么请注意输出值是一个二进制序列,您可以合并input1和input2以获得一个数字。考虑这个解决方案:
typedef enum
{
NO_MOVEMENT,
DIRECTION_B,
DIRECTION_A,
ERROR,
MASK = 0x3 // just defensive programming, you might not need it
} output_t;
output_t get_output (unsigned int input1, unsigned int input2)
{
return (input1<<1 | input2) & MASK;
}
在gcc/x86上进行基准测试,它有4条指令分支自由(并且很可能是内联的候选):
get_output:
add edi, edi
or edi, esi
mov eax, edi
and eax, 3
ret
不使用防御性编程:
typedef enum
{
NO_MOVEMENT,
DIRECTION_B,
DIRECTION_A,
} output_t;
output_t get_output (unsigned int input1, unsigned int input2)
{
return input1<<1 | input2;
}
拆卸:
get_output:
lea eax, [rdi+rdi]
or eax, esi
ret
即使使用LUT,也无法超越这个性能。
在我看来,原来的方法已经足够好了。为了便于阅读,也可以使用开关…
AltInput = (input1 <<1) | input2;
则可以定义一个enum,如下所示:
枚举:
NO_MOVEMENT = 0,
DIRECTION_B,
DIRECTION_A,误差
然后你可以用:
开关(AltInput)
{
案例NO_MOVEMENT:
…
打破;
case DIRECTION_B:
打破;
case DIRECTION_A:
…
打破;
default:
…
}