【问题标题】:Assigning int x = 'abc' ;分配 int x = 'abc' ;
【发布时间】:2010-11-14 12:08:03
【问题描述】:

我正在做代码审查,我看到单引号字符串分配给枚举值:

枚举 { Option_1 = 'a', 选项_2 = 'b' } ;

虽然这使得代码更易读(尽管枚举的含义应该与 num 的名称差不多),但对我来说看起来很傻。

我不知道你可以这样做,在研究之后,我可以看到所发生的一切都是你使用的“字符”的二进制值被扔进一个 int。

在实践中还有其他人这样做吗?或者这是一种不好的做法?

【问题讨论】:

  • 顺便说一句:您的主题行(“Assigning int x = 'a'”)表明枚举和整数是相同的。虽然相似,但它们是不同的,不应被视为可互换的。
  • 另外,为了挑剔,这里没有作业。
  • 嗯,枚举中的各个元素是int 的,对吧?
  • @GMan 嗯,它们是整数。
  • @GMan:见stackoverflow.com/questions/1122096/…“C++ 枚举的底层类型是什么”

标签: c++


【解决方案1】:

您好,请考虑一下我为您制作的这个简单示例, 如您所见,以这种方式使用枚举是合法的。就我而言,我将它们用作一种 类的内部常量。享受吧。

#include <iostream>

using namespace std;

class VegetableBasket
{
    enum { Max_Potatoes = 2 };  // This is a legal usage...
    enum { Max_Tomatoes = 3 };  // In here the enums serve as class's internal constants
    public :
        // Constructors
        VegetableBasket() : tomatoes(0), potatoes(0) {}
        VegetableBasket(int t, int p) : tomatoes(t), potatoes(p) 
        { 
            if(tomatoes > Max_Tomatoes) 
                tomatoes = Max_Tomatoes;
            if(potatoes > Max_Potatoes)
                potatoes = Max_Potatoes;
        }
        // Accessors
        int getMaxPotatoes() const { return Max_Potatoes; }
        int getMaxTomatoes() const { return Max_Tomatoes; }
        int getPotatoes() const { return potatoes; }
        int getTomatoes() const { return tomatoes; }
    private :
        int tomatoes;
        int potatoes;
};


void main()
{
    VegetableBasket basket1(1, 1);
    VegetableBasket basket2(5, 6);

    cout << "The basket holds : " << basket1.getMaxPotatoes() 
         << " max potatoes, and " << basket1.getMaxTomatoes()
         << " max tomatoes" << endl;

    cout << "Basket 1 holds : " << basket1.getPotatoes()
         << " potatoes and "    << basket1.getTomatoes()
         << " tomatoes" << endl;

    cout << "Basket 2 holds : " << basket2.getPotatoes()
         << " potatoes and "    << basket2.getTomatoes()
         << " tomatoes" << endl;
}

【讨论】:

  • 不错的代码,但如果示例常量是字符,它会更明显相关。另外,为了挑剔,我花了一点时间来理解你在做什么,因为你为两条枚举行布置 cmets 的方式至少对我暗示(错误地)你在做一种Max_Potatoes 的事情和 Max_Tomatoes 的另一种事情。换句话说,cmets 最初给我的印象是 Max_Potatoes 是一个合法的例子,而 Max_Tomatoes 是一个类内部枚举如何做某事的例子。
【解决方案2】:

不是单引号字符串——它是一个字符文字。在枚举中使用字符文字本质上与将 char 分配给 int 相同——这是完全合法的,并且在许多情况下都非常有用。

【讨论】:

  • ty - 修正了问题的标题
【解决方案3】:

您甚至可以分配最终最多为 32 位整数的多字节“值”:

enum t_f_fnf
{
    true = 'true',
    false = 'fals',
    file_not_found = 'fnf!'
};

(向dailywtf点头。:))

【讨论】:

  • 天哪,这真的可以编译吗?我从来不知道你可以在一个字符文字中包含多个(非转义)字符......
  • 另外,字节序在这里起作用了吗?
  • 是的,它可以编译。我最近第一次自己遇到它,也不敢相信。我想如果你为每个枚举值分配一个完整的 32 位值,字节序就会发挥作用。
  • 请记住,“多字符文字具有 int 类型和实现定义的值”(2.13.2,第 1 段),因此您得到的正是实现定义的。我希望字节序很重要。
  • 是的,这正是问题的重点。问题是,做你上面列出的事情对我来说看起来很愚蠢。你在dailywtf哪里找到的?
【解决方案4】:

我觉得没问题,你愿意:

enum
{
  Option_1 = 97,
  Option_2 = 98
} ;

【讨论】:

    【解决方案5】:

    有时在实际值很重要的情况下使用具有显式值的枚举。如果这些值是“字母 a 的 ascii 值”,为什么不通过分配 'a' 告诉读者?

    【讨论】:

      【解决方案6】:

      字符只是 1 字节的整数,为什么不呢?

      【讨论】:

      • 字符文字大于“char”。这是 getc() 正常工作所必需的。
      • 不正确,dmckee。根据标准(2.13.2.1):“包含单个c-char的普通字符文字具有char类型,其值等于执行字符集中c-char编码的数值。”跨度>
      • :) 在你的辩护getc() 确实返回一个int,所以试图用类似的东西存储结果:char c = getc(...);是不正确的。跨度>
      • 这是 C 和 C++ 不同的地方之一(或至少 C95)。在 C 中,char 字面量是一个 int,这对于允许除字符之外的额外值很有用。在 C++ 中,char 字面量是 char,它是允许运算符重载工作所必需的。
      【解决方案7】:

      除非某处的代码期望 Option_1 为“a”,否则我看不到好处。

      【讨论】:

        【解决方案8】:

        根据 ISO C 和 C++ 标准,这绝对是完全合法的。如果将这些枚举值作为这些字符序列化为文本(例如 CSV)文件,这是一种相当合理的做法。否则,我认为没有多大意义。我想它可以带来一些调试好处,但是我知道的所有优秀的 C/C++ 调试器都可以将枚举值解析为相应的符号。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-04-08
          • 1970-01-01
          • 2017-05-18
          • 2013-10-15
          • 2013-12-05
          • 2015-11-21
          • 2014-10-10
          • 2011-09-03
          相关资源
          最近更新 更多