简体   繁体   English

更有效的方法来编码c ++中的else语句

[英]More Efficient way to code if then else statements in c++

I'm coding in c++ for the Nintendo DS, but this should be universal with all c++. 我用C ++编写了Nintendo DS编码,但这应该适用于所有c ++。

I already know about switch statements, but I need to make a set of if, then, and else that have multiple arguments: 我已经知道了switch语句,但是我需要创建一组if,then和else,它们有多个参数:

void doSomething(int number)
{
...
}

bool left = true;
bool right = false;
bool top = false;
bool bottom = false;

if (left && top && right)
    doSomething(1);
else if (top && right && bottom)
    doSomething(2);
else if (left && right && bottom)
    doSomething(3);
else if (left && top && bottom)
    doSomething(4);

Any help is appreciated. 任何帮助表示赞赏。

You can convert the four booleans into a binary number 0..15, and use an array to look up the parameter, like this: 您可以将四个布尔值转换为二进制数0..15,并使用数组来查找参数,如下所示:

int location = (left   ? 1<<0 : 0)
             | (right  ? 1<<1 : 0)
             | (top    ? 1<<2 : 0)
             | (bottom ? 1<<3 : 0);

Now location has a number from 0 to 15, so you can do this: 现在location的数字从0到15,所以你可以这样做:

int lookup[] = {-1, -1, -1, -1, -1, -1, -1,  1, -1, -1, -1, 3, -1, 4, 2, -1};
int arg = lookup[location];
if (arg != -1) {
    doSomething(arg);
}

If you are really a psycho (or obfuscator), you could use something like bitmasks: 如果你真的是一个心理学家(或混淆器),你可以使用像bitmasks这样的东西:

unsigned char direction = 8;  // 1 0 0 0  for  l r t b

or by staying consistent with the convention you used in your question: 或者与您在问题中使用的惯例保持一致:

unsigned char direction = left + (right << 1) + (top << 2) + (bottom << 3);

and then you will have (*) : 然后你会有(*)

switch(direction) {
    case 14:  // 1 1 1 0
        doSomething(1);
        break;
    case 7:  // 0 1 1 1
        doSomething(2);
        break;
    case 13:  // 1 1 0 1
        doSomething(3);
        break;
    case 11:  // 1 0 1 1
        doSomething(4);
        break;
}

And if you need to access the individual value conveniently: 如果您需要方便地访问单个值:

inline bool left() {return (direction & 8) == 8;}
inline bool right() {return (direction & 4) == 4;}
inline bool top() {return (direction & 2) == 2;}
inline bool bottom() {return (direction & 1) == 1;}

Actually, this should be pretty fast... 实际上,这应该很快......


(*) As an alternative, you could also write: (*)作为替代方案,你也可以写:

const unsigned char left_c = 8;
const unsigned char right_c = 4;
const unsigned char top_c = 2;
const unsigned char bottom_c = 1;

And test the combination like this ( constant-expression are accepted in switches): 并像这样测试组合(在开关中接受常量表达式 ):

switch(direction) {
    case (left_c + right_c + top_c):
        doSomething(1);
        break;
    ...
}

Encapsulate this into a getSide () that returns an enum. 将其封装到返回枚举的getSide()中。 I assume that the boolean variables are accessible from the class implementing or calling doSomething 我假设布尔变量可以从实现或调用doSomething的类中访问

    ...
    bool left = true;
    bool right = false;
    bool top = false;
    bool bottom = false;
    ...
    doSomething(getSide());
    ...

    enum Side {
    Top, Bottom,  Left, Right
    }

    void doSomething(Side side)
    {
    ...
    }

    Side getSide () {
    if (left && top && right) //Bottom Border
        return Side.Bottom;
    else if (top && right && bottom) //Left Border
        return Side.Left;
    else if (left && right && bottom) //Top Border
        return Side.Top;
    else if (left && top && bottom) //Right Border
        return Side.Right;
    }

I am adding this response just to show how can a std::bitset could be used for this purpose. 我添加此响应只是为了说明如何将std::bitset用于此目的。 I am aware that maybe your target platform will not support the C++11 Standard, but hopefully this can help someone else. 我知道也许你的目标平台不支持C ++ 11标准,但希望这可以帮助其他人。

#include<iostream>
#include<bitset>
#include<vector>
#include<map>

// The location is represented as a set of four bits; we also need a
// comparator so that we can later store them in a map.
using Location = std::bitset<4>;
struct LocationComparator {
  bool operator()(const Location& loc1, const Location& loc2) const {
    return loc1.to_ulong() < loc2.to_ulong();
  }
};

// the callback (handler) has a signature "void callback()"
using Callback = void (*)( );

// the mapping between location and callback is stored in a simple
// std::map
using CallbackMap = std::map<Location, Callback, LocationComparator>;

// we define the fundamental locations
const Location Top   ("1000");
const Location Bottom("0100");
const Location Right ("0010");
const Location Left  ("0001");

// ... and define some actions (notice the signature corresponds to
// Callback)
void action_1() { std::cout<<"action 1"<<std::endl;}
void action_2() { std::cout<<"action 2"<<std::endl;}
void action_3() { std::cout<<"action 3"<<std::endl;}
void action_4() { std::cout<<"action 4"<<std::endl;}

// ... now create the map between specific locations and actions
// (notice that bitset can perform logical operations)
CallbackMap callbacks = {
  { Top    | Right , action_1 },
  { Top    | Left  , action_2 },
  { Bottom | Right , action_3 },
  { Bottom | Left  , action_4 },
};

// an abstract game element has a location, the interaction will
// depend on the defined callbacks
class GameElement {
 public:
  GameElement(const Location& location)
      : m_location(location) { }

  void interact() const {
    callbacks[m_location]();
  }

  virtual ~GameElement() { } // so that others can inherit
 private:
  Location m_location;
};

int main() {
  // create a vector of game elements and make them interact according
  // to their positions

  std::vector<GameElement> elements;

  elements.emplace_back(Top    | Right);
  elements.emplace_back(Top    | Left);
  elements.emplace_back(Bottom | Right);
  elements.emplace_back(Bottom | Left);

  for(auto & e : elements) {
    e.interact();
  }

}

I compiled it on OS X using GCC 4.7.2 using the following command: 我使用GCC 4.7.2使用以下命令在OS X上编译它:

g++ locations.cpp -std=c++11

The output is: 输出是:

action 1
action 2
action 3
action 4

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 C++ 如何使 if 语句更有效率 - C++ how to make if statements more efficient 是通过hash_map调用函数指针 <string, fnPtr> 比C ++中的多个if / else if / else语句更有效或更好的样式? - Is a calling a function pointer through a hash_map<string, fnPtr> more efficient or better style than multiple if/else if/else statements in C++? 优雅的 C++ 代码:如何使用 while 循环和条件语句编写更高效的代码 - Elegant C++ Code: How to write more efficient code using while loops and conditional statements C++ If/else if 语句 - C++ If/else if statements C++编程更高效的方法 - C++ programming more efficient way to do 切换或if语句-在C ++中更清楚 - Switch or else if statements - what is more clear in C++ 有什么方法可以使这个相对简单(嵌套用于内存复制)C ++代码更高效? - Any way to make this relatively simple (nested for memory copy) C++ code more efficient? Arduino / C ++ IF / ELSE语句 - Arduino/C++ IF/ELSE statements 有没有更有效的方法来替换这些多个IF语句? - Is there a more efficient way to replace these multiple IF statements? 在 C++ 中更高效、更快速的矩阵求逆方法(大和小) - More efficient and fast way of inverting matrices in c++ (big and small)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM