你好,C++(13)这道单选题的答案是A、B、C还是D?3.7 枚举类型

3.7  枚举类型

除了之前我们介绍的数值数据和文字数据之外,在现实世界中,常常还会遇到这样一类数据:一道单选题的答案只能是A、B、C、D四个选项中的某一个;红绿灯的颜色只能是红色,绿色和黄色中的某一种;一个人的性别只能是男性或者女性。这种数据都只有有限的几种可能值,其值也只能是这个范围内的某一个。为了抽象和表达这种特殊数据,C++提供了枚举机制。

使用C++的枚举机制,我们可以通过列举某种数据的所有可能值来定义一种新的数据类型,这种数据类型通常被称为枚举类型。反过来,当使用枚举类型来定义变量时,这个变量的取值也就限定在了枚举类型所列举出的可能取值范围内。定义一个枚举类型的语法格式如下:

enum 枚举类型名
{
    // 可能的枚举值列表
}; // 注意,这里必须以分号表示结束

其中,enum是定义枚举类型的关键字;枚举类型名是所要创建的新数据类型的名字,完成枚举类型的定义后,我们可以用它作为数据类型来定义变量;而在枚举类型的定义中,可以逐个列出这个枚举类型的所有可能值。例如,可以将描述交通灯颜色的数据抽象成一个枚举类型:

// 交通灯颜色
enum TrafficLight
{
    RED,     // 红
    GERRN,  // 绿
    YELLOW  // 黄
};

有了这样的TrafficLight枚举类型的定义,我们就可以用它做为数据类型来定义一个变量,用以表示交通灯的颜色:

// 定义一个变量light表示交通灯的颜色
// 将枚举值RED赋值给它,表示当前交通灯是红色
TrafficLight light = RED;

因为枚举类型所表达数据的特殊性,使我们在应用枚举类型时需要注意以下几点。

1. 枚举类型中的枚举值有对应的默认整数值

在本质上,枚举类型数据是一个整型数值,每个枚举类型的可选值其实是一个整数值。在默认情况下,第一个枚举值对应的是整数值0,第二个是1,以此类推。例如,上面TrafficLight枚举类型中的RED可选值其实就是整数值0,而GREEN就是1,YELLOW自然就是2了。如果认为枚举值的默认对应整数值不合适。比如,在某些情况下,我们希望某个枚举值拥有特殊的整数值以表示特殊含义,这时也可以在定义的时候另行指定各个枚举值对应的整数值。例如:

// 另行指定各个枚举值对应的整数值
enum TrafficLight
{
    RED = 1, // 指定对应的整数值,不再是从0开始
    GERRN,  // 2
    YELLOW = 0   // 指定对应的整数值为0,表示特殊含义
};

经过人为地指定枚举值对应的数值后,RED对应的整数值就变为了1,其后的GREEN增加一个自然也就随之而变为2,而对于最后的YELLOW,因为其特殊意义,我们又人为地将其指定为0。

2. 枚举类型变量的赋值

如果变量是枚举类型,那就只能使用这种枚举类型的某个枚举值对其进行赋值。例如:

// 红灯
TrafficLight light = RED;
// 变为绿灯
light = GREEN;
// 如果是用枚举值之外的数据对其进行赋值,会导致编译错误
// 即使这个值是某个枚举值对应的整数值
light = 1;

换句话说,如果想把某个变量的取值限定在某几个可选值范围之内,则可以把这个变量定义为枚举类型变量。

3. 枚举值是常量,定义后不可改变其对应整数值

在定义枚举类型时,就已经完成了枚举值的定义,其对应的数值不是默认数值就是给定的特殊数值。定义完成后,各个枚举值的数值就成为了常量,要按照常量来处理,不能对其进行赋值。也就是说,不能在完成定义后再改变其中某个枚举值对应的整数值。例如,下面的语句是非法的:

RED = 4;  // 尝试改变枚举值,导致编译错误

枚举类型中的枚举值实质是一些整型常量。在上面的例子中,完全可以使用3个整型常量来表示交通灯的三种颜色。但是,枚举类型允许我们用描述性的名称来表示某个有限范围内的整数值,而不是直接使用含义模糊的整数值,这有助于确保给变量指定合法的期望值,同时这也使得我们的代码意义明确,更具可读性,也更易于维护。所以,如果要表达的数据“只有有限的几种可能值”时,我们应该优先选择使用枚举类型。

知道更多:带作用域的枚举类

虽然枚举类型可以方便地定义某个范围内的枚举值。但是,因为传统的枚举类型在本质上是一个int类型的整数,因此在使用中,也常常存在各种各样的问题。例如,传统枚举类型的所有枚举值在其定义后的代码范围内都是可以使用的,而这可能会造成名字污染,使得其后的代码就不能再把这个枚举值名字用作其他用途;不可以指定枚举类型的底层数据类型,这可能会浪费内存资源,同时也使得枚举类型不可以进行前向声明。所谓前向声明,就是在某个元素(函数或者类)尚未定义的时候,为了提前使用它而进行的声明,向编译器表明源文件中有这个元素的定义,现在就可以放心大胆地使用,而具体的定义会在稍后给出。正是为了解决传统枚举类型所存在的这些问题,C++11提出了新的具有作用域,并可以指定底层数据类型的枚举类。

定义枚举类的语法形式跟定义一个传统的枚举类型的语法形式十分相似:

enum class 枚举类名:数据类型
{
    // 可能的枚举值列表
};

枚举类的定义以“enum class”开始,后面跟上枚举类名,其后还可以用冒号“:”指定枚举类的底层数据类型。枚举类的底层数据类型必须是有符号或无符号的整型数,如果不指定,其默认的数据类型是int类型。例如:

// 定义一个枚举类TrafficLight,
// 并指定其底层数据类型为char类型
enum class TrafficLight : char
{
    RED = 1, // 红
    GERRN,  // 绿
    YELLOW  // 黄
};

虽然枚举类的定义同传统的枚举类型的定义十分相似,但是因为两者内在机制的不同,他们已经是完全不同的两个概念。枚举类具有作用域,其枚举值只在其作用域内可见,这就很好地解决了枚举值可能引起的名字污染问题。例如:

// 枚举值RED属于TrafficLight作用域
// 所以我们必须在其前面加上TrafficLight才能访问
TrafficLight light = TrafficLight::RED;
// 定义一个名为RED的变量,虽然与枚举值RED同名,
// 但是两者不会产生冲突,也就是枚举值RED的定义
// 没有引起名字污染
bool RED = true;

除了解决名字污染问题之外,因为可以指定枚举的底层数据类型,这使得前向声明成为可能,同时,根据枚举值的多少,选择合适的底层数据类型,也可以在一定程度上避免资源的浪费。例如:

// 使用前的前向声明,只是声明了枚举类的名字,
// 没有定义具体的枚举值
enum class TrafficLight : char;
// 使用前向声明的枚举类
void foo(TrafficLight* light)
{
    // ...
}

// …

// 补充完成枚举类的定义
enum class TrafficLight : char
{
    RED = 1, // 红
    // …
};

在这段代码中,我们完成枚举类TrafficLight枚举类的前向声明后,就可以直接使用了。而在最后,我们只需要补充上它的具体定义即可。另外,我们在这里指定了枚举值的底层数据类型为char,这要比默认的int更加节省资源。

从上面的例子我们可以看到,枚举类的使用,很好地解决了传统的枚举类型在使用中所遇到的各种问题,所以,在以后的编程实践中,我们应该优先选择使用枚举类。

时间: 2024-07-31 13:24:18

你好,C++(13)这道单选题的答案是A、B、C还是D?3.7 枚举类型的相关文章

(转载)你好,C++(13)这道单选题的答案是A、B、C还是D?3.7 枚举类型

你好,C++(13)这道单选题的答案是A.B.C还是D?3.7 枚举类型 3.7  枚举类型 除了之前我们介绍的数值数据和文字数据之外,在现实世界中,常常还会遇到这样一类数据:一道单选题的答案只能是A.B.C.D四个选项中的某一个:红绿灯的颜色只能是红色,绿色和黄色中的某一种:一个人的性别只能是男性或者女性.这种数据都只有有限的几种可能值,其值也只能是这个范围内的某一个.为了抽象和表达这种特殊数据,C++提供了枚举机制. 使用C++的枚举机制,我们可以通过列举某种数据的所有可能值来定义一种新的数

[单选题]function foobar( ) { $a = func_get_args( ); return $a[2];}print foobar('a',1,'b',2);输出是什么?

2 a b 1 a2 获取一个函数的所有参数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 function foo() {     $numargs = func_num_args(); //参数数量     echo "参数个数是: $numargs<br />\n";     if ($numargs >= 2) {         echo "第二个参数的值:" . func_get_arg(1) . "<

[单选题]有关PHP引用的说法,错误的是

[单选题]有关PHP引用的说法,错误的是: unset一个引用,只是断开了变量名和变量内容之间的绑定,这并不意味着变量内容被销毁了. PHP引用本质就是指针,在函数调用范围内可以绑定到别的变量上面. 在一个对象的方法中,$this永远是调用它的对象的引用. 可以将一个变量通过引用传递给函数,这样该函数就可以修改其参数的值. 正确答案: 很遗憾,没答对,再接再厉! 答案解析 引用只是值内存块的别名,而指针是一个实体,存放的值内存地址,需要额外分配内存空间.

[单选题]一个php文件的地址为c:/apache/htdocs/phptutor/index.php,虚拟主机的地址是c:/apache/htdocs,那么$_SERVER[&#39;PHP_SELF&#39;]应该评价到哪个页面

index.php /htdocs/phptutor/index.php /phptutor/index.php c:/apache/htdocs/phptutor/index.php $_SERVER['PHP_SELF'] #当前正在执行脚本的文件名,与 document root相关.$_SERVER['argv'] #传递给该脚本的参数.$_SERVER['argc'] #包含传递给程序的命令行参数的个数(如果运行在命令行模式).$_SERVER['GATEWAY_INTERFACE']

[单选题]以下脚本输出什么?&lt;?php $array = array (0.1 =&gt; &#39;a&#39;, 1.2 =&gt; &#39;b&#39;); echo count ($array);?&gt;

2 空 0 1 答案是A [单选题]以下脚本输出什么?<?php $array = array (0.1 => 'a', 1.2 => 'b'); echo count ($array);?>

13.删除单链表中重复的元素

13.删除单链表中重复的元素 思路: 用Hashtable辅助,遍历一遍单链表就能搞定.同高级函数9的原因,我不太会使用C++STL中的hash.而如果使用set集合来存储链表中的所有的值,实际上效率和每次重新遍历单链表是一样的.“用了c++标准库中的set来保存访问过的元素,所以很方便的就可以判断当前节点是否在set集合中,直接使用set提供的find函数就可以了.而且使用set的查找在时间复杂度上比较低.”我不太清楚STL中set集合的实现方式,如果是基于类似hash结构的话,那自然效率O(

[单选题]range(&#39;a&#39;, &#39;z&#39;)返回什么?

这个函数的调用会抛出一个异常 false 按字母顺序排列的a到z 在字母表中a和z的距离 PHP range() 函数 PHP Array 函数 实例 创建一个包含从 "0" 到 "5" 之间的元素范围的数组: <?php $number = range(0,5); print_r ($number); ?> 运行实例 定义和用法 range() 函数创建一个包含指定范围的元素的数组. 该函数返回一个包含从 low 到 high 之间的元素的数组. 注释

[单选题]下面的代码输出什么?$i = 5; print $i++ + ++$i;

11 10 12 13 正确答案:

[单选题]isset()的功能是( )

测试常量是否存在 测试常量是否为空 测试变量是否存在 测试变量是否为空 PHP isset() 嗨豆壳 在线手册 科技资讯 技术文章 尼玛导航 hi-docs / php / isset 定义和用法 检测变量是否已声明. 类似$_POST['index']的变量,如果不存在表单提交,就会出现:Notice:Undefined index:...的错误. 语法 isset(var1,var2,..) 参数 描述 var1 要检查的变量. var2 变量2 例子 1 <?php $var = '';