当我遇到这个问题时我正在编码,我想知道这是正确的还是出于性能原因可以改进:
if (color == 0) {
if (c.val[0] >= 0 && c.val[0] <= 64) {
//Black
Paint(cursor.x + x, cursor.y + y);
}
}
else if (color == 1) {
if (c.val[0] >= 64 && c.val[0] <= 128) {
//Grey
Paint(cursor.x + x, cursor.y + y);
}
}
else if (color == 2) {
if (c.val[0] >= 128 && c.val[0] <= 192) {
//White Gray
Paint(cursor.x + x, cursor.y + y);
}
}
您可以看到即时消息在所有IF语句中执行的操作完全相同,而且看起来有点怪异,该程序可以按我的意愿工作,但我真的认为即时消息缺少某些内容。
谢谢!
答案 0 :(得分:5)
由于结构,
if (color >= 0 && color <= 2) {
if (c.val[0] >= 64*color && c.val[0] <= 64*(color+1)) {
Paint(cursor.x + x, cursor.y + y);
}
}
答案 1 :(得分:1)
一些逻辑运算使其更紧凑。
if ((color == 0 && c.val[0] >= 0 && c.val[0] <= 64) ||
(color == 1 && c.val[0] >= 64 && c.val[0] <= 128) ||
(color == 2 && c.val[0] >= 128 && c.val[0] <= 192)) {
Paint(cursor.x + x, cursor.y + y);
}
答案 2 :(得分:0)
重复这么短的代码并不太可怕,但是出于“不要重复自己”的考虑,并且如果以后需要更多代码,则可以简单地将测试分开,以决定是否要执行某些操作从实际操作中,使用标志。
bool need_Paint = false;
if (color == 0) {
// Black?
need_Paint = (c.val[0] >= 0 && c.val[0] <= 64);
}
else if (color == 1) {
// Grey?
need_Paint = (c.val[0] >= 64 && c.val[0] <= 128);
}
else if (color == 2) {
// White Gray?
need_Paint = (c.val[0] >= 128 && c.val[0] <= 192);
}
if (need_Paint)
Paint(cursor.x + x, cursor.y + y);
(请注意,编译器的优化可能无需实际将bool
放入内存中就可以处理这种事情,如果合适的条件为真,则直接跳转到函数调用语句。)
(这看起来也像通常写成switch
的那种模式。您可以考虑使用该语法而不是所有的if
。)
但是实际上,这个特定的代码可以变得更加简单,因为您正在执行的三个不同测试具有直接的数学模式:
if (color >= 0 && color <= 2 && // (if these aren't already guaranteed)
c.val[0] >= 64*color && c.val[0] <= 64*(color+1)) {
Paint(cursor.x + x, cursor.y + y);
}
(要考虑的另一件事可能是使用enum ColorType { BLACK=0, GREY=1, WHITE_GRAY=2 };
而不是直接写“幻数” 0
,1
和2
。但是如果同时使用enum
和此代码的数学版本,尽管enum
的默认值始终从零开始连续计数,但我还是建议您指定显示的确切值,以使您清楚重新指望那些值。)
答案 3 :(得分:0)
我更喜欢您的原始帖子,而不是所选内容。
这是另一种方法,具有大约相同的行数...但是我发现它更具可读性。
void yourSnippet() {
switch (color) {
case 0: { PaintIf( 0, 64); } break; // black
case 1: { PaintIf( 64, 128); } break; // Grey
case 2: { PaintIf(128, 192); } break; // White Gray
} // switch
}
void PaintIf(int min, int max) {
if ((c.val[0] >= min) && (c.val[0] <= max))
Paint(cursor.x + x, cursor.y + y);
}
答案 4 :(得分:0)
另一个与2785528's answer相似的解决方案,但使用lambda以避免将其他参数传递给PaintIf
:
const auto PaintIf = [&](int min, int max)
{
if (min <= c.val[0] && c.val[0] <= max)
Paint(cursor.x + x, cursor.y + y);
};
switch (color)
{
case 0: PaintIf( 0, 64); break;
case 1: PaintIf( 64, 128); break;
case 2: PaintIf(128, 192);
}
答案 5 :(得分:0)
(从c ++ 17开始)尽可能保证Lambda是constexpr(即零成本抽象)。
它们有时可以允许更简洁和可维护的逻辑表达:
auto range = [](int color)
{
auto min = color * 64;
auto max = min + 64;
return std::make_tuple(min, max);
};
auto in_range = [](auto val, auto tuple)
{
auto [min, max] = tuple;
return val >= min && val <= max;
};
if (in_range(c.val[0], range(color)))
Paint(cursor.x + x, cursor.y + y);
答案 6 :(得分:-1)
vector<int> limits = {0, 64, 128, 192};
if (0 <= color && color <= 2) {
if (c.val[0] >= limits[color] && c.val[0] <= limits[color + 1]) {
Paint(cursor.x + x, cursor.y + y);
}
}
解决这个问题的方法如下:代码中不应有未命名的常量(嗯,至少最好避免使用它们)。然后您会注意到其中有很多,因此将它们存储在数组中是合乎逻辑的。