- 浏览: 442506 次
- 性别:
- 来自: 济南
文章分类
- 全部博客 (470)
- 前言 (1)
- 【sys】centos6.2 (51)
- 【sys】shell (8)
- 【sys】yum (1)
- software (6)
- 【tec】ruby (16)
- 【tec】rails (35)
- 【tec】rails路由 (2)
- 【tec】rails部署 (10)
- 【tec】rails优化 (6)
- 【tec】rails测试 (11)
- 【tec】php (45)
- 【tec】android (1)
- 【tec】ios (125)
- 【data】mysql (11)
- web (6)
- 【life】文学与提升 (2)
- life (36)
- 【life】怀念 (1)
- 【web】nginx (5)
- 【web】网络与安全 (4)
- 工作随笔 (1)
- 【software】svn (5)
- 【script】jquery (10)
- powerEdge (2)
- 杂七杂八 (5)
- 【sys】ubuntu (9)
- 【sys】windows (4)
- 【tec】java (1)
- 【tec】html (3)
- 【tec】c++ (38)
- 【tec】汇编 (1)
- 【data】数据库 (1)
- 【exchange 】学术交流 (1)
- 【tec】域名空间 (1)
- 【tec】编程先知 (1)
- 【tec】网站建设 (7)
- 【sys】mac (24)
- 【sys】seo (1)
- 【tec】wp (1)
- 【software】git (4)
最新评论
-
fireDragonpzy:
呵呵 貌似我网站上的有更新 你从那里看看 这个博客维护的不及时 ...
牛人经典语录 -
Peppermintchz:
还真这么2过啊!!好怀念啊
牛人经典语录 -
fireDragonpzy:
chenhong53 写道你好,我想问一下,能不能给一组精灵数 ...
cocos2d-x事件触发的优先级 -
chenhong53:
你好,我想问一下,能不能给一组精灵数组中的精灵添加触屏优先级, ...
cocos2d-x事件触发的优先级 -
fireDragonpzy:
dreamstar1020 写道谢谢庞兄指点,写的很详细,谢谢 ...
致:上海郑兄(虚拟主机-web服务器搭建)
至从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
发表评论
-
C++ 虚函数表解析 转
2013-05-29 09:09 765详情请参考:【Software Myzone】:http:// ... -
不玩设计模式的程序员不是好程序员
2013-05-02 09:40 623详情请参考:【Software Myzone】:http:// ... -
C/C++中的结构体
2012-11-07 09:02 708详情请参考:【Software Myzone】:http:// ... -
C++数组的存储|C++数组所占内存空间
2012-09-17 19:45 710详情请参考:【Software Myzone】:http:// ... -
C++中引用传递与指针传递区别(进一步整理)
2012-09-04 13:37 791详情请参考:【Software MyZone】:http:// ... -
提高C程序效率的方法
2012-08-14 18:21 424本文为firedragonpzy原创,转载务必在明显处注明: ... -
const char*, char const*, char*const的区别
2012-08-13 13:50 831const char*, char const*, char* ... -
“tr”和字符串类型的string str = "tr"对比
2012-08-11 16:11 908本文为firedragonpzy原创,转载务必在明显处注明: ... -
c++ sizeof使用
2012-08-11 15:22 824http://dev.yesky.com/143/256364 ... -
typedef分析(针对ccColor4B)
2012-08-09 19:34 1209本文为firedragonpzy原创, ... -
c++中的变量
2012-08-09 17:24 742本文为firedragonpzy原创, ... -
C++引用与指针的比较
2012-08-03 14:09 733引用是C++中的概念,初学者容易把引用和指针混淆一起。 ... -
C/C++中函数指针的含义
2012-08-01 15:54 926函数存放在内存的代 ... -
vs2010惯用快捷键设置
2012-07-27 19:54 946首先介绍下快捷键设置入口:工具->选项->环境 ... -
几种函数调用方式
2012-07-27 15:33 935几种函数调用方式 __cdecl 是C De ... -
c++基础知识(十一)文件的复制
2012-07-25 08:49 724#include <cstdio> #inc ... -
字符编码笔记:ASCII,Unicode和UTF-8
2012-07-18 14:04 9561. ASCII码 我们知道,在 ... -
c++基础知识(十)学习C++静态成员注意事宜
2012-07-14 17:49 838C++中的一个类中还可以 ... -
c++ site
2012-07-14 09:45 714c++,含有内核的讲解:http://bdxnote.blog ... -
c++进阶(一)C语言条件编译及编译预处理阶段
2012-07-14 09:09 1333一、C语言由源代码生成的各阶段如下: C源程序->编译 ...
相关推荐
C++中枚举类型(enum)
常见的enum类型重定义的解决方法,清晰明了。
在C++中,枚举类型分为不限定作用域(enum)和限定作用域(enum class)。 2. enum与enum class的区别? (为什么需要限定作用域?) 答:枚举作用域是指枚举类型成员名字的作用域,起自其声明之处,终止枚举定义...
STL vector 容器介绍 C++中布尔类型 深入探讨C++中的引用 C/C++中枚举类型(enum)
C++ 基础知识总结目录C++ 面试基础知识总结 1位域 5C 实现 C++ 类 7friend 友元类和友元函数 8:: 范围解析运算符 9enum 枚举类型
C++ 11起引入的 enum class相对于传统的enum有了很多变化,主要是针对传统 enum 在编程过程中出现的值类型名称作用域、enum类型安全问题进行了改良. 一、传统enum类型 先来看看传统enum在编程过程中可能遇到的一些...
C#与C调用C++,非托管,含struct调用及enum公用,完整项目,可直接编译或运行。 项目将所有工程的输出统一到Debug。 vs2015+Framework4.6,注意工程的配置。 所有东西自写,只是出于样例参考的作用,所以代码规范...
enum类型的本质[文].pdf
介绍选项为Enum和OptionSet类型提供功能,例如: 除了RawType rawValue外,还提供其他值类型能够在Enum和OptionSet类型之间互换对Codable OptionSet使用其他值类型 例子假设您有Enum类型: enum ...
enum类型被intent所携带时各种情况的示例代码, MainActivity.java三处需解注释,分别来单独运行
源码,有兴趣可下载自己看看,和我在文章中贴出的代码相同
NULL 博文链接:https://rensanning.iteye.com/blog/2013734
详细介绍c++ 枚举类型enum用法,word doc格式,大家都能用
枚举字符串C++ 枚举可与字符串相互转换。 源代码是从几个来源收集的,并稍作修改。 代码中引用了原始来源。例子# include " enum_conversions_macro.h "ENUM_CLASS (Day, Monday, Tuesday, Wednesday, Thursday, ...
enum day {Sun,Mon,Tue,Wed,Thu,Fri,Sat}; 默认情况下,枚举符的值从0开始,其后值总是前面一个+1。 即Sun=0,Mon=1,Tue=2,Wed=3,Thu=4,Fri=5,Sat=6 也可以自己定义数值,其后值总是前面一个+1 例如: enum day {Sun=...
自己秋招根据面经和基础知识学习总结的知识点,主要内容包括但不限于:volatile关键字、sizeof & strlen、const的作用、enum、inline、delete[] 与 delete、多态的作用、C++与Python的区别、深拷贝与浅拷贝、extern ...
c++11新增了enum class,相比传统的enum好处多了很多,但也有些让人不太爽的地方,如:输出到std流时会报错,进行了强转则没有信息输出,那么,到底该如何将enum class的值出到std流呢? 提供这个enum class的原因是...
DoctrineEnumBundle, 在Symfony应用程序中,为 Doctrine 提供enum 类型的支持 DoctrineEnumBundle为 enum 应用程序中的Doctrine 提供类型支持。 支持平台sql SQLite sql SQLite安装通过编辑器添加依赖项co
c#遍历枚举(ENUM)类型的方法,简单实用,适合c#初学者