首先,我所指的一个例子:
UINT f, i, s;
CONST UINT k[5] = { VK_LBUTTON, VK_RBUTTON, VK_MBUTTON, VK_XBUTTON1, VK_XBUTTON2 };
for (f = RI_MOUSE_LEFT_BUTTON_DOWN, i = 0, s = RI_KEY_MAKE; f != RI_MOUSE_WHEEL; f <<= 1, i += s, s = !s)
if ((pMouseData->usButtonFlags & f) == f)
SetVKeyState(k[i], s);
与此相比:
if (pMouseData->usButtonFlags & RI_MOUSE_LEFT_BUTTON_DOWN)
SetVKeyState(VK_LBUTTON, RI_KEY_MAKE);
if (pMouseData->usButtonFlags & RI_MOUSE_LEFT_BUTTON_UP)
SetVKeyState(VK_LBUTTON, RI_KEY_BREAK);
if (pMouseData->usButtonFlags & RI_MOUSE_RIGHT_BUTTON_DOWN)
SetVKeyState(VK_RBUTTON, RI_KEY_MAKE);
if (pMouseData->usButtonFlags & RI_MOUSE_RIGHT_BUTTON_UP)
SetVKeyState(VK_RBUTTON, RI_KEY_BREAK);
if (pMouseData->usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_DOWN)
SetVKeyState(VK_MBUTTON, RI_KEY_MAKE);
if (pMouseData->usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_UP)
SetVKeyState(VK_MBUTTON, RI_KEY_BREAK);
if (pMouseData->usButtonFlags & RI_MOUSE_X1_BUTTON_DOWN)
SetVKeyState(VK_XBUTTON1, RI_KEY_MAKE);
if (pMouseData->usButtonFlags & RI_MOUSE_X1_BUTTON_UP)
SetVKeyState(VK_XBUTTON1, RI_KEY_BREAK);
if (pMouseData->usButtonFlags & RI_MOUSE_X2_BUTTON_DOWN)
SetVKeyState(VK_XBUTTON2, RI_KEY_MAKE);
if (pMouseData->usButtonFlags & RI_MOUSE_X2_BUTTON_UP)
SetVKeyState(VK_XBUTTON2, RI_KEY_BREAK);
后面的代码显然是一个完全展开的循环。
这实际上是一个关于可读性或减少冗余(在代码的不同区域中的重复语句中)是否从长远来看更好的问题。
我更关心稍后在大型代码库的上下文中访问它。当然,减少修改区域的数量是一件好事; for
循环的初始化和更新语句是否有点麻烦?
有没有人经历过这个,可能是微不足道的问题。
答案 0 :(得分:4)
关键是只压缩完全相同的陈述:
const UINT k[5] = { VK_LBUTTON, VK_RBUTTON, VK_MBUTTON, VK_XBUTTON1, VK_XBUTTON2 };
static_assert( (RI_MOUSE_LEFT_BUTTON_DOWN << 2) == RI_MOUSE_RIGHT_BUTTON_DOWN );
for ( UINT i = 0; i < _count_of(k); ++i ) {
if (pMouseData->usButtonFlags & (RI_MOUSE_LEFT_BUTTON_DOWN << 2*i))
SetVKeyState(k[i], RI_KEY_MAKE);
if (pMouseData->usButtonFlags & (RI_MOUSE_LEFT_BUTTON_UP << 2*i)))
SetVKeyState(k[i], RI_KEY_BREAK);
}
所有逗号运算符都消失了,异常的循环增量消失了,符号变量仍然用于键状态。
我认为这比原版更容易阅读,因为它适用于一页代码,重复很明显。
编辑:现在记录了旗帜关系假设。
我实际上可能会:
struct { UINT vk; UINT downflag; UINT upflag;
} const k[] = {
{ VK_LBUTTON, RI_MOUSE_LEFT_BUTTON_DOWN, RI_MOUSE_LEFT_BUTTON_UP },
{ VK_RBUTTON, RI_MOUSE_RIGHT_BUTTON_DOWN, RI_MOUSE_RIGHT_BUTTON_UP },
...
};
for ( UINT i = 0; i < _count_of(k); ++i ) {
if (pMouseData->usButtonFlags & k[i].downflag)
SetVKeyState(k[i].vk, RI_KEY_MAKE);
if (pMouseData->usButtonFlags & k[i].upflag)
SetVKeyState(k[i].vk, RI_KEY_BREAK);
}
以正确的顺序删除使用相邻位的标志的假设。
你可以使用后一个版本,使第二个参数成为SetVKeyState
一个表列,但IMO失去了有价值的配对结构。