替换long switch语句

时间:2015-09-18 10:34:28

标签: c++ switch-statement case

只是想知道是否有更干净的方法来做到这一点。用户将致电setFullScaleRange1setFullScaleRange2。他们将设置的范围值只是整数形式。然后进入switch语句并转换为十六进制值。我不希望用户必须发送十六进制值,所以这就是为什么我有这种迂回的方式。有没有更有效的方法呢?

void label::setFullScaleRange1(uint16_t range)
{
    uint8_t data = 0;
    uint8_t user_range = 0;
    user_range = get_user_range(range, true);
    data = SET_SLICE(data, REG_TEST1, user_range);
    spi_reg_write(data, REG_CONFIG);
}

void label::setFullScaleRange2(uint16_t range)
{
    uint8_t data = 0;
    uint8_t user_range = 0;
    user_range = get_user_range(range, false);
    data = SET_SLICE(data, REG_TEST2, user_range);
    spi__write(data, REG_CONFIG);
}


static uint8_t get_user_range(uint16_t range, bool test_range)
{   
    if(test_range) {
        switch(range) {
        case 125: 
            range = SET_125_DEG_SEC;
            break;
        case 250: 
            range = SET_250_DEG_SEC;
            break;
        case 500: 
            range = SET_500_DEG_SEC;
            break;
        case 1000:
            range = SET_1000_DEG_SEC;
            break;
        case 2000:
            range = SET_2000_DEG_SEC;
            break;
        default:
            return 1;
        }
    } else {
        switch(range) {
        case 2: 
            range = SET_2G;
            break;
        case 4: 
            range = SET_4G;
            break;
        case 8: 
            range = SET_8G;
            break;
        case 16:
            range = SET_16G;
            break;
        default:
            return 1;
        }
    }
    return range;
}

3 个答案:

答案 0 :(得分:4)

在C ++中,您可以为get_user_range提供一组static个映射,用于存储要返回的各种常量

#include <cstdint>
#include <iostream>
#include <map>

enum E1 { SET_125_DEG_SEC = 125, SET_250_DEG_SEC = 250, SET_500_DEG_SEC = 500, SET_1000_DEG_SEC = 1000, SET_2000_DEG_SEC = 2000 };
enum E2 { SEG_2G = 2, SEG_4G = 4, SEG_8G = 8, SEG_16G = 16 };

static int get_user_range(uint16_t range, bool test_range)
{   
    static std::map<uint16_t, int> switch_map[2] = 
    {
        { 
            {  125, SET_125_DEG_SEC },
            {  250, SET_250_DEG_SEC },
            {  500, SET_500_DEG_SEC },
            { 1000, SET_1000_DEG_SEC },
            { 2000, SET_2000_DEG_SEC }
        },
        { 
            {  2, SEG_2G },
            {  4, SEG_4G },
            {  8, SEG_8G },
            { 16, SEG_16G }
        }
    };

    auto const& m = switch_map[test_range];
    auto it = m.find(range);
    if (it != m.end()) {
        return it->second;
    }

    return 1;
}

int main()
{
    std::cout << get_user_range(500, false) << '\n';
    std::cout << get_user_range( 16, false) << '\n';
    std::cout << get_user_range(500, true) << '\n';
    std::cout << get_user_range( 16, true) << '\n';
}

Live Example

此代码的作用是使用布尔值test_range索引map-array。然后给定正确的映射,它将使用整数find调用其range成员函数。如果这个函数返回一个迭代器(基本上是一个指针,如果你来自C),它等于一个超过地图结尾的迭代器,它还没有找到你要找的东西。如果是这种情况,则返回1.否则,取消引用迭代器,该迭代器提供std::pair<uint16_t, int>结构,并且您获取包含所需值的.second数据成员。

您可以轻松地将其转换为C风格的数组,您可以在其中执行类似的操作。但是你必须更加努力地搜索数据。

请注意,我将返回类型更改为int,以便能够为各种枚举常量提供自然值。

答案 1 :(得分:0)

是的, 制作一个指向函数的指针数组做一些算法,将数字的范围从大数字改为单个数字, 有一些方法可以做到这一点。 (enum可选!) 并且您的算法会更短,没有任何switch或manny if语句。

答案 2 :(得分:0)

如果输入值和输出值之间存在某种数学关系,您可以计算输出值,这是迄今为止效率最高的。

否则,您必须将所有输入存储在已排序的数组中,然后将所有输出存储在另一个已排序的数组中。二进制搜索输入数组中的特定值,获取找到它的数组索引,然后从输出表中获取相应的值。

或者,您可以创建一个包含一个输入值和一个输出值的结构/类,然后创建这些结构/类的数组。

  • 在C中,您可以使用bsearch()功能。
  • 在C ++中,您可以使用std :: set或std :: map等容器,并使用std :: find进行搜索。