RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 614809
Accepted
maestro
maestro
Asked:2020-01-15 15:08:32 +0000 UTC2020-01-15 15:08:32 +0000 UTC 2020-01-15 15:08:32 +0000 UTC

枚举中是否有数字

  • 772

该程序从外部设备的闪存中读取一个数字(整数,1 字节,无符号)。对于其编程解释,使用枚举:

enum BoardType {
    Classic = 0,
    Static = 1,
    Smart = 2
}
BoardType t = (BoardType)getBoardType();

问题是肉眼可见的:内存中包含的数字不一定包含在枚举中。而且我认为在运行时没有办法检查返回的数字是否正确,但这将是强制性的,因为闪存在擦除状态下存储值 0xFF,而其他数字最终在那里因为我的歪手也可以到达那里。那么,有没有办法检查返回的数字是否包含在枚举中,如果没有,以编程方式解释这个数字的正确方法是什么?

c++
  • 3 3 个回答
  • 10 Views

3 个回答

  • Voted
  1. Harry
    2020-01-15T15:22:54Z2020-01-15T15:22:54Z

    总的来说,没办法。因为它们只是整数值的约定。
    因此,如果您真的需要,那么要么检查范围(如果枚举没有“间隙”,要么有一组单独的值 并检查其中是否存在。

    我想是的。(c) 绒毛

    • 5
  2. yrHeTateJlb
    2020-01-15T17:30:56Z2020-01-15T17:30:56Z

    专门针对您的示例,您可以这样做:

    enum BoardType{
        Classic = 0,
        Static = 1,
        Smart = 2,
        NumberOfBoardTypes
    };
    
    bool isCorrect(BoardType t){
        return t >= 0 && t < NumberOfBoardTypes;
    }
    

    或者像这样:

    enum BoardType{
        Classic = 0,
        Static = 1,
        Smart = 2,
        Unknown
    };
    
    BoardType getBoardType(){
        BoardType t = static_cast<BoardType>(42);
    
        if(t < 0 || t > Unknown){
            t = Unknown;
        }
    
        return t;
    }
    

    UPD:对于有“漏洞”的情况,enum你可以这样做:

    enum BoardType{
        Classic = 0,
        Static = 1,
        Smart = 2
    };
    
    std::set<BoardType> boardTypes(){
        std::set<BoardType> types;
        types.insert(Classic);
        types.insert(Static);
        types.insert(Smart);
    
        return types;
    }
    
    bool isCorrect(BoardType t){
        static const std::set<BoardType> types = boardTypes();
        return types.count(t);
    }
    
    • 5
  3. Best Answer
    Majestio
    2020-01-15T20:37:32Z2020-01-15T20:37:32Z

    我建议,如果我们在谈论速度和少量命令,只需使用表转换。而且桌子不会太大。

    代码示例(链接到 ideone):

    #include <iostream>
    
    enum class BoardType : uint8_t { 
      Classic = 0,
      Static = 1,
      Smart = 2,
      Bad = 255  
    };
    
    BoardType Cast[UINT8_MAX];     // <- сюда просто забить константы -++
                                                                       //
    inline BoardType ToEnum(const uint8_t i) {                         //
      BoardType Ret = Cast[i];                                         //
      if (Ret == BoardType::Bad) throw std::range_error("Беда");       //
      return Ret;                                                      //
    }                                                                  //
                                                                       //
    int main () {                                                      //
      ////// вместо  инициализации ниже - ///////////////////////////////  
      for(auto i=0; i<UINT8_MAX; i++) Cast[i] = BoardType::Bad;
      Cast[0] = BoardType::Classic;
      Cast[1] = BoardType::Static;
      Cast[2] = BoardType::Smart; 
      //////////////////////////////////////////////////////////////////  
      try {  
        std::cout << static_cast<int>(ToEnum(0)) << std::endl;  
        std::cout << static_cast<int>(ToEnum(1)) << std::endl;
        std::cout << static_cast<int>(ToEnum(2)) << std::endl;
        std::cout << static_cast<int>(ToEnum(3)) << std::endl;  
      } catch(std::range_error &e) {
        std::cout << "range_error: " << e.what() << std::endl;  
      } catch(...) {
        std::cout << "что-то совсем пошло не так" << std::endl;  
      }    
      return 0;        
    }
    

    结论:

    0
    1
    2
    range_error: Беда
    

    首先,您可以使用该函数ToEnum()在异常处理块中捕获“不正确”的值。

    其次,使用表Cast很容易与BoardType::Bad异常处理比较“烦人”。

    第三,如果有几十个“命令”,它switch的可读性会更差,并且处理速度可能会更慢。

    • 4

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    Python 3.6 - 安装 MySQL (Windows)

    • 1 个回答
  • Marko Smith

    C++ 编写程序“计算单个岛屿”。填充一个二维数组 12x12 0 和 1

    • 2 个回答
  • Marko Smith

    返回指针的函数

    • 1 个回答
  • Marko Smith

    我使用 django 管理面板添加图像,但它没有显示

    • 1 个回答
  • Marko Smith

    这些条目是什么意思,它们的完整等效项是什么样的

    • 2 个回答
  • Marko Smith

    浏览器仍然缓存文件数据

    • 1 个回答
  • Marko Smith

    在 Excel VBA 中激活工作表的问题

    • 3 个回答
  • Marko Smith

    为什么内置类型中包含复数而小数不包含?

    • 2 个回答
  • Marko Smith

    获得唯一途径

    • 3 个回答
  • Marko Smith

    告诉我一个像幻灯片一样创建滚动的库

    • 1 个回答
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Алексей Шиманский 如何以及通过什么方式来查找 Javascript 代码中的错误? 2020-08-03 00:21:37 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    user207618 Codegolf——组合选择算法的实现 2020-10-23 18:46:29 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5