- 浏览: 2052061 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (795)
- java (263)
- 聚类搜索引擎 (9)
- 经验之谈 (67)
- DSP (3)
- C++ (140)
- Linux (37)
- SNMP (6)
- Python (6)
- 数据库 (61)
- 网络 (20)
- 算法 (15)
- 设计模式 (4)
- 笔试题 (38)
- 散文 (35)
- 数据结构 (9)
- 银行知识 (0)
- 榜样 (9)
- Lucene (15)
- Heritrix (6)
- MetaSeeker (0)
- netbeans (12)
- php (3)
- 英语 (8)
- DB2 (0)
- java基础 (5)
- mongodb & hadoop (4)
- Javascript (7)
- Spring (4)
- ibatis & myibatis (1)
- velocity (1)
- 微服务 (0)
- paddle (1)
- 第三方 (0)
- 知识沉淀 (1)
- 建模 (0)
最新评论
-
0372:
标示对java很陌生!
中文乱码解决的4种方式 -
梦留心痕:
Java中\是转意字符, 可是你的这句话我没看懂,只要把得到的 ...
java中如何忽略字符串中的转义字符--转载 -
yanjianpengit:
[b][/b]
java为什么非静态内部类里面不能有静态成员 -
springdata-jpa:
可以参考最新的文档:如何在eclipse jee中检出项目并转 ...
eclipse 如何把java项目转成web项目 -
qq1130127172:
,非常好。
(转)SpringMVC 基于注解的Controller @RequestMapping @RequestParam..
enum类型的本质 至从C语言开始enum类型就被作为用户自定义分类有限集合常量的方法被引入到了语言 当中,而且一度成为C++中定义编译期常量的唯一方法(后来在类中引入了静态整型常量)。 根据上面对enum类型的描述,到底enum所定义出来的类型是一个什么样的类型呢?作为 一个用户自定义的类型其所占用的内存空间是多少呢?使用enum类型是否真的能够起到有限 集合常量的边界约束呢?大家可能都知道enum类型和int类型具有隐示(自动)转换的规则, 那么是否真的在任何地方都可以使用enum类型的变量来代替int类型的变量呢?下面会逐一 回答这些问题。 1. 到底enum所定义出来的类型是一个什么样的类型呢? 在C++中大家都知道仅仅有两种大的类型分类:POD类型和类类型(不清楚的可以参 见我的其他文章)。enum所定义的类型其实属于POD类型,也就是说它会参与到POD 类型的隐示转换规则当中去,所以才会出现enum类型与int类型之间的隐示转换现象。 那么也就是说enum所定义的类型不具备名字空间限定能力(因为不属于类类型), 其所定义的常量子具备和enum类型所在名字空间相同的可见性,由于自身没有名字 限定能力,所以会出现名字冲突现象。如: struct CEType { enum EType1 { e1, e2 }; enum EType2 { e1, e2 }; }; 上面的例子会出现e1、e2名字冲突编译时错误,原因就在于枚举子(e1、e2)是 CEType名字空间中的名字,同样在引用该CEType中的枚举子时必须采用CEType::e1 这样的方式进行,而不是CEType::EType1::e1来进行引用。 2. 作为一个用户自定义的类型其所占用的内存空间是多少呢? 该问题就是sizeof( EType1 )等于多少的问题,是不是每一个用户自定义的枚举类 型都具有相同的尺寸呢?在大多数的32位编译器下(如:VC++、gcc等)一个枚举类 型的尺寸其实就是一个sizeof( int )的大小,难道枚举类型的尺寸真的就应该是int 类型的尺寸吗?其实不是这样的,在C++标准文档(ISO14882)中并没有这样来定义, 标准中是这样说明的:“枚举类型的尺寸是以能够容纳最大枚举子的值的整数的尺寸”, 同时标准中也说名了:“枚举类型中的枚举子的值必须要能够用一个int类型表述”, 也就是说,枚举类型的尺寸不能够超过int类型的尺寸,但是是不是必须和int类型 具有相同的尺寸呢?上面的标准已经说得很清楚了,只要能够容纳最大的枚举子的 值的整数就可以了,那么就是说可以是char、short和int。例如: enum EType1 { e1 = CHAR_MAX }; enum EType2 { e2 = SHRT_MAX }; enum EType3 { e3 = INT_MAX }; 上面的三个枚举类型分别可以用char、short、int的内存空间进行表示,也就是: sizeof( EType1 ) == sizeof( char ); sizeof( EType2 ) == sizeof( short ); sizeof( EType3 ) == sizeof( int ); 那为什么在32位的编译器下都会将上面三个枚举类型的尺寸编译成int类型的尺寸呢? 主要是从32位数据内存对其方面的要求进行考虑的,在某些计算机硬件环境下具有对 齐的强制性要求(如:sun SPARC),有些则是因为采用一个完整的32位字长CPU处理 效率非常高的原因(如:IA32)。所以不可以简单的假设枚举类型的尺寸就是int类 型的尺寸,说不定会遇到一个编译器为了节约内存而采用上面的处理策略。 3. 使用enum类型是否真的能够起到有限集合常量的边界约束呢? 首先看一下下面这个例子: enum EType { e1 = 0, e2 }; void func1( EType e ) { if ( e == e1 ) { // do something } // do something because e != e1 must e == e2 } void func2( EType e ) { if ( e == e1 ) { // do something } else if ( e == e2 ) { // do something } } func1( static_cast<EType>( 2 ) ); func2( static_cast<EType>( -1 ) ); 上面的代码应该很清楚的说明了这样一种异常的情况了,在使用一个操出范围的整 型值调用func1函数时会导致函数采取不该采取的行为,而第二个函数可能会好一些 他仅仅是忽略了超出范围的值。这就说明枚举所定义的类型并不是一个真正强类型 的有限常量集合,这样一种条件下和将上述的两个函数参数声明成为整数类型没有 任何差异。所以以后要注意标准定义中枚举类型的陷阱。(其实只有类类型才是真 正的强类型) 4. 是否真的在任何地方都可以使用enum类型的变量来代替int类型的变量呢? 通过上面的讨论,其实枚举类型的变量和整型变量具有了太多的一致性和可互换性, 那么是不是在每一个可以使用int类型的地方都可以很好的用枚举类型来替代呢? 其实也不是这样的,毕竟枚举类型是一个在编译时可区分的类型,同时第2点的分析 枚举类型不一定和int类型具有相同的尺寸,这两个差异就决定了在某些场合是不可 以使用枚举类型来代替int类型的。如: 第一种情况: enum EType { e1 = 0, e2, e3 }; EType val; std::cin >> val; 第二种情况: enum EType { e1 = 0, e2, e3 }; EType val; std::scanf( "%d", &val ); 上面的两种情况看是基本上属于同一种类型的问题,其实不然。第一种情况会导致 编译时错误,会因为std::cin没有定义对应的枚举类型的重载>>运算符而出错,这 就说明枚举类型是一种独立和鉴别的类型;而第二种情况不会有任何编译时问题, 但是可能会导致scanf函数栈被破坏而使得程序运行非法,为什么会这样呢?上面 已经分析过了枚举类型变量的尺寸不一定和int类型相同,这样一来我们采用%d就 是说将枚举类型变量val当作4字节的int变量来看待并进行参数压栈,而在某些编 译器下sizeof( val )等于1字节,这样scanf函数就会将val变量地址中的后续的三 字节地址也压入栈中,并对其进行赋值,也许val变量后续的三个字节的地址没有 特殊含义可以被改写(比如是字节对齐的空地址空间),可能会认为他不会出现错 误,其实不然,在scanf函数调用结束后会进行栈清理,这样一来会导致scanf函数 清理了过多的地址空间,从而破坏了外围函数的栈指针的指向,从而必然会导致程 序运行时错误。 由上面的说明枚举类型有那么多的缺点,那我们怎样才能够有一个类型安全的枚举类型 呢?其实可以采用类类型来模拟枚举类型的有限常量集合的概念,同时得到类型安全的好处, 具体参见后续的文章。 文章转自:http://www.cppblog.com/chemz/archive/2007/06/05/25578.html |
<script src="tag.php?action=relatetag&rtid=136858" type="text/javascript"></script>
发表评论
-
DLL中导出函数的声明有两种方式:
2012-11-12 16:42 1877DLL中导出函数的声明有两种方式: 一种方式是:在函数声明中 ... -
k-means算法的C++实现
2011-04-05 11:38 2350k-means算法的C++实现: http://www.ku ... -
main()中的参数
2010-10-31 10:41 1547所有的应用程序都是从以main函数作为入口, 而mai ... -
static作用
2010-10-26 19:15 2399转自(from http://www.cnb ... -
mmap函数
2010-10-25 22:41 1920mmap函数的使用方法 UNIX ... -
C语言中三种内存分配方式
2010-10-25 20:23 01.malloc 原型:extern void *ma ... -
位拷贝和值拷贝
2010-10-23 15:37 1609为了便于说明我们以String类为例: 首先定义String ... -
(转帖)把类的析构函数写成虚函数的用意
2010-10-23 15:10 1707#include <iostream.h> cl ... -
动态规划/贪心算法----0/1背包问题AND普通背包问题
2010-10-23 14:03 6837两个背包问题都是比较典型的问题,对这两种算法的理解有很好的帮助 ... -
netstat, nslookup, finger, ping命令
2010-10-22 17:13 1553Netstat用于显示与IP、TCP ... -
C++返回值
2010-10-22 16:53 1568C++函数返回值: (1)正常情况下,函数的参数要复制一份在 ... -
switch语句后的表达式的值
2010-10-22 16:23 1852一般格式: switch (表达式) { case 常量 ... -
C++四种强制类型转换
2010-10-19 11:45 1584显式类型转换又被称之 ... -
C++四种强制类型转化的区别
2010-10-19 11:43 1364先介绍const_cast和reinterpret_cast: ... -
Visual C++线程同步技术剖析:临界区,时间,信号量,互斥量
2010-10-18 14:24 1840使线程同步 在程序中使用多线程时,一般很少有多个线程能在其 ... -
(转)临界区,互斥量,信号量,事件的区别
2010-10-18 14:22 1779四种进程或线程同步互斥的控制方法1、临界区:通过对多线程的串行 ... -
(转)在C++中实现同步锁,类似synchronize(object){....}
2010-10-18 13:49 1891在做C++的项目中发现, ... -
C++线程同步
2010-10-18 13:46 1626线程同步是多 ... -
C++多线程编程
2010-10-18 10:56 1760今天我给大家讲一讲C++ ... -
关于C++对函数传参与函数返回值进行引用传递的详解
2010-10-16 22:51 4072关于C++对函数传参与函数返回值进行引用传递的详解 ...
相关推荐
《enum类型的本质——深入解析与应用》 在软件开发中,enum类型是一个常见的工具,用于定义一组相关的命名常量。自C语言起,enum就已经被引入,为用户提供了一种定义有限集合常量的方式。在C++中,enum类型进一步...
枚举类型本质上是整数类型,可以是`byte`、`sbyte`、`short`、`ushort`、`int`、`uint`、`long`或`ulong`之一,但默认类型为`int`。如果需要指定其他类型,可以在枚举声明时指定: ```csharp enum Colors : byte { ...
#### 一、Enum的本质与特性 `Enum`,作为Java语言中的一个关键字,自JDK 5.0引入以来,便赋予了开发者一种全新的数据类型——枚举类型,其设计初衷在于为编程提供更安全、更简洁的方式来处理固定集合的常量。不同于...
虽然枚举类型本质上是整型,但不推荐直接进行类型转换,因为这样可能导致意料之外的行为。不过,C语言标准允许将枚举变量赋值给整型变量,反之亦然,但需要注意枚举类型的底层大小可能与int不同。 4. 枚举的大小:...
值得注意的是,枚举类型本质上是一个特殊的类,它继承自`java.lang.Enum<E>`。这意味着枚举类型可以拥有构造函数、方法和属性,就像任何其他类一样。 #### 枚举的实现机制 当编译上述枚举时,Java编译器会生成一个...
JavaScript中的枚举类型(enum)并不是语言内建的特性,如C#或Java等其他语言。然而,开发者可以通过模拟枚举的行为来实现类似的功能。在JavaScript中,我们通常使用对象(object)来模拟枚举,就像示例代码中所示。...
2. **枚举值的类型**:默认情况下,枚举值的类型是`int`,但可以通过`enum class`或`enum struct`指定基础类型。 3. **命名空间**:`enum class`或`enum struct`创建的枚举具有自己的作用域,防止与全局或类内的其他...
枚举(Enum)作为编程语言中一种特殊的类型,为开发者提供了一种简洁、清晰的定义一组命名常量的方式。在C#语言中,枚举是通过`enum`关键字定义的,其本质上是一种结构体,与整型(int)紧密相关联,但提供了更丰富...
Java中的枚举(enum)是自JDK 1.5版本引入的一种强大的类型,它用于定义一组相关的常量。枚举在Java中被设计为一种特殊的类,它们默认继承自`java.lang.Enum`抽象类,并且是单继承的,这意味着它们无法再继承其他类...
枚举类型本质上是一种受限制的类,它自动继承自`java.lang.Enum`类,同时也实现了`Comparable`和`Serializable`接口。这意味着枚举实例可以进行比较,并且可以序列化保存。`java.lang.Enum`类的部分声明如下: ```...
同时,由于枚举元素本质上是整型常量,系统会为枚举变量分配整数类型所需的存储空间。 总的来说,枚举类型是程序设计中一种非常实用的工具,它帮助我们组织代码,提高代码的可读性和可维护性。通过理解枚举类型的...
- **枚举类型**:`enum`。 **引用类型** - **字符串类型**:`string`。 - **数组类型**。 - **类类型**:用户自定义的类。 - **接口类型**。 - **委托类型**。 **特殊类型** - **空类型**:`null`。 - **动态...
这两种类型的本质差异在于它们如何在内存中存储和处理。 1. 通用类型系统(Common Type System, CTS) CTS是.NET Framework的核心组成部分,它定义了一套标准的数据类型,所有.NET语言编译后的IL代码都基于这些类型...
由于枚举类型本质上是类,所以它们可以作为参数传递,也可以作为返回类型。此外,枚举可以实现接口,从而实现多态性。 ```java interface Shape { void draw(); } enum Shapes implements Shape { CIRCLE {...
Enum为枚举提供基类,其基础类型可以是除 Char 外的任何整型,如果没有显式声明基础类型,则使用Int32。 注意:枚举类型的基类型是除 Char 外的任何整型,所以枚举类型的值是整型值 1、C#将枚举转为字符串(enume->...
枚举类型(enum)本质上是整型的一种包装,因此枚举常量可以被转换为对应的整型值,反之亦然。但枚举类型的具体底层类型(如int或unsigned int)取决于编译器和平台,因此在跨平台代码中应谨慎使用枚举到整型的转换...
同时,由于枚举类型本质上是整数,所以可以参与常规的整数运算和比较。 5. **枚举变量的作用域** 枚举变量的作用域遵循C语言的一般规则,即定义在哪就作用于哪。如果在函数内部定义,则只在该函数内部可见;如果在...
当我们使用enum定义了一个枚举类型之后,其枚举值列表本质上就是一系列整数值,而且是从0开始依次递增的。尽管在C语言中enum被视为一种数据类型,但它在使用时与整型没有什么区别,既可以作为函数参数、函数返回值,...
在PHP中,枚举(Enum)类型长期以来并没有作为语言的内建类型被支持,但开发者仍可以通过一些方式实现类似枚举的行为。随着PHP版本的更新,PHP社区提供了基于SPL(Standard PHP Library)的扩展库来模拟枚举,以及...
枚举常量在本质上是整型常量,可以参与数值运算,例如赋值、比较和算术操作。下面的语句都是合法的: ```c enum weeks today = MON; today = 1; today++; ``` 枚举常量与#define定义的宏常量相似,但它们有区别。...