【发布时间】:2011-09-21 09:02:08
【问题描述】:
已在此站点上发布了如何通过执行以下操作来生成唯一的枚举常量:
enum _EXAMPLE
{
LEFT = 'left',
RIGHT = 'right'
//etc
};
忽略有效性问题,数字是如何产生的?更具体地说,使用什么技术?因为我希望尝试构建一个模拟短字符串的函数。
【问题讨论】:
已在此站点上发布了如何通过执行以下操作来生成唯一的枚举常量:
enum _EXAMPLE
{
LEFT = 'left',
RIGHT = 'right'
//etc
};
忽略有效性问题,数字是如何产生的?更具体地说,使用什么技术?因为我希望尝试构建一个模拟短字符串的函数。
【问题讨论】:
'left' 是一个多字符文字(C++03 的 2.13.2/1),它的类型为 int。
它是由实现定义的它实际具有的整数值。特别是,不能保证 'left' 和 'right' 不相等,所以在枚举中使用它们会很失败。
不过,例如,GCC 在此处记录其行为:http://gcc.gnu.org/onlinedocs/gcc-4.6.1/cpp/Implementation_002ddefined-behavior.html#Implementation_002ddefined-behavior
'right' 有五个字符,显然不可能每个 5 个字符的字符串都有不同的 32 位值。
【讨论】:
'left' 将具有相同的值。不过,不同的编译器可能会给出不同的值。 'c' 不是多字符文字,它的类型为char,等于执行字符集中小写字母“c”的数值。
char 签名的系统上,您可能会发现é 的值是负数,而如果您采用平台对它如何形成多字符常量的定义并将其应用于单字符字符串é,你得到一个正值。它们可能等于模 256,这看起来很合理,但这完全取决于实现。
char,多字符文字的类型为 int。
'left' 和'right' 不相等。如果有人问有关 C++ 的问题,但没有指定任何实现,那么除非另有说明,否则我会从该语言的 POV 回答。
多字符常量是您通常想要避免的。假设您的系统是具有 32 位架构的小端序。在这种情况下,'left' 转换为:
('l')+('e'<<8)+('f'<<16)+('t'<<24)
请注意,为了便于阅读,我在每个字符后面省略了 int 的转换。
所以多字符常量实际上是一个整数。
我曾经使用'BM' 来检查我读取的 .bmp 图像的前两个字节,以检查文件类型是否正确,但很快我决定不值得我保存额外的几个字符。如果你使用大端系统,或者你的int 有不同的大小等等,你会在那里遇到问题。更不用说烦人的编译器警告了。
如果你有enum,通常有两种情况:
案例 1,你不关心枚举的值。在这种情况下,你就不要管它们了。第一个将变为零,编译器会逐步填充其余部分。
案例 2,您需要这些值来达到一个巧妙的目的。在这种情况下,您需要为您的目的一一分配它们。例如,如果您想enum 程序的子系统并且您需要启用、禁用它们,您可以有 1 个变量,它是 enum 的或 (|) 值,如下所示:
enum subsystem
{
SUBSYSTEM_1 = 0x0001,
SUBSYSTEM_2 = 0x0002,
SUBSYSTEM_3 = 0x0004,
SUBSYSTEM_4 = 0x0008,
SUBSYSTEM_5 = 0x0010,
/* etc */
};
(有趣的事实,你知道 C++ 在enum 的最后一个元素之后接受额外的, 吗?)
在任何情况下,您都不会想要一个对应于'left' 的奇怪值。如果您认为这样可以使代码清晰易读,那么您可以确定常量的名称 (LEFT) 就足够了。
【讨论】:
WRITE+BINARY,它更具可读性并且具有相同的语法(请注意,由于enum 的位ed 值不重叠,+ 的作用类似于 |