枚举大小sizeof 中枚举的大小详解

合集下载

sizeof函数用法

sizeof函数用法

sizeof函数用法sizeof函数是C语言中非常常用的一个函数,它主要用于计算数据类型或变量的大小。

在C语言中,sizeof函数的语法格式为sizeof(表达式),其中表达式可以是数据类型、变量或者表达式。

sizeof函数返回的是一个unsigned int类型的值,表示表达式所占用的字节数。

在实际使用中,sizeof函数通常用于动态分配内存空间、计算数组的长度以及判断数据类型的大小。

首先,sizeof函数可以用来计算数据类型的大小。

例如,sizeof(int)会返回int类型所占用的字节数,通常为4个字节。

sizeof(char)会返回char类型所占用的字节数,通常为1个字节。

sizeof(float)会返回float类型所占用的字节数,通常为4个字节。

通过sizeof函数,我们可以在不同的平台上准确地获取数据类型的大小,从而编写更加通用的代码。

其次,sizeof函数还可以用来计算变量的大小。

例如,如果有一个整型变量int num,可以通过sizeof(num)来获取num所占用的字节数,通常为4个字节。

这在编写程序时非常有用,可以帮助我们动态地分配内存空间,确保变量的大小符合需求。

另外,sizeof函数还可以用来计算数组的长度。

在C语言中,数组的长度可以通过sizeof(array) / sizeof(array[0])来计算,其中array为数组的名称。

这个用法非常常见,可以帮助我们在不知道数组长度的情况下准确地获取数组的长度,从而避免数组越界的错误。

总的来说,sizeof函数在C语言中是一个非常有用的函数,可以帮助我们获取数据类型的大小、变量的大小以及数组的长度。

通过sizeof函数,我们可以编写更加通用、健壮的代码,提高程序的可读性和可维护性。

因此,熟练掌握sizeof函数的用法对于C语言程序员来说是非常重要的。

c 枚举定义

c 枚举定义

c 枚举定义枚举(Enumeration)是C语言中的一种数据类型,用于定义一组具有互相关联的、离散的、有限的取值范围的常量集合。

枚举类型可以简化程序编写过程,提高代码的可读性和可维护性。

本文将介绍C语言中枚举的定义方式,以及在实际应用中的使用方法。

一、枚举的定义C语言中,通过关键字"enum"来定义枚举类型。

枚举类型的定义格式如下:```enum 枚举类型名 {枚举常量1,枚举常量2,...};```其中,枚举类型名是用户自定义的标识符,用于表示整个枚举类型。

枚举常量是具体的取值,用逗号分隔。

枚举常量的值默认从0开始,依次递增。

例如,我们定义一个表示星期的枚举类型:```cenum Week {MON,TUE,WED,THU,FRI,SAT,SUN};```在上述代码中,我们定义了一个枚举类型"Week",其中包含了七个枚举常量,分别表示星期一到星期日。

二、枚举的使用枚举类型可以像其他数据类型一样使用,在程序中可以声明枚举类型的变量,并对其赋值。

例如:```cenum Week today = MON;```上述代码中,我们声明了一个名为"today"的枚举类型的变量,并将其赋值为星期一对应的枚举常量"MON"。

枚举变量的赋值只能使用枚举常量,不能直接使用整数值。

在枚举类型中定义的枚举常量是唯一的,可以直接使用常量名来进行赋值操作,提高了代码的可读性。

枚举类型的变量可以进行比较操作,以判断其是否相等。

例如:```cenum Week day1 = MON;enum Week day2 = TUE;if (day1 == day2) {printf("两个枚举变量相等\n");} else {printf("两个枚举变量不相等\n");}```上述代码中,我们通过比较两个枚举变量"day1"和"day2"的值,得出它们是否相等的结论。

c语言枚举详解

c语言枚举详解

c语言枚举详解在C语言中,枚举(enum)是一种用户定义的数据类型,它允许您为一组相关的常量分配描述性的名字。

枚举类型通常用于表示一组固定数量的选项或状态。

枚举的基本语法如下:```cenum 枚举名称 {枚举值1,枚举值2,枚举值3,...};```例如,如果我们想表示一周中的几天,我们可以定义一个名为`DayOfWeek`的枚举类型:enum DayOfWeek {MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUNDAY};```在这个例子中,`MONDAY`、`TUESDAY`等都是枚举值,它们都是`DayOfWeek`枚举类型的有效值。

您也可以使用描述性的名字作为枚举值,例如:```cenum DayType {WORKDAY,WEEKEND,HOLIDAY```枚举类型的使用:1. 作为变量类型:您可以声明一个变量并给它分配一个枚举值。

例如:```cDayType myDay = WORKDAY; // myDay 是DayType枚举类型的一个变量,它的值为WORKDAY。

```2. 在switch语句中使用:由于枚举值是整数,因此您可以在switch语句中使用它们。

例如:```cenum DayType day = WEEKEND;switch(day) {case WORKDAY:printf("Today is a workday.\n");break;case WEEKEND:printf("Today is the weekend.\n");break;case HOLIDAY:printf("Today is a holiday.\n");break;}```注意事项:枚举类型是有符号的,它们的默认整数类型是int,但可以通过指定其他整数类型来改变。

例如,您可以将枚举类型的整数类型设置为short、char等。

C语言32个关键字详解

C语言32个关键字详解

C语言中32个关键字详解由ANSI标准定义的C语言关键字共32个:auto double int struct break else long switchcase enum register typedef char extern return unionconst float short unsigned continue for signed voiddefault goto sizeof volatile do if while static根据关键字的作用,可以将关键字分为数据类型关键字和流程控制关键字两大类。

1数据类型关键字A基本数据类型(5个)void:声明函数无返回值或无参数,声明无类型指针,显式丢弃运算结果char:字符型类型数据,属于整型数据的一种int:整型数据,通常为编译器指定的机器字长float:单精度浮点型数据,属于浮点数据的一种double:双精度浮点型数据,属于浮点数据的一种B类型修饰关键字(4个)short:修饰int,短整型数据,可省略被修饰的int。

long:修饰int,长整形数据,可省略被修饰的int。

signed:修饰整型数据,有符号数据类型unsigned:修饰整型数据,无符号数据类型C复杂类型关键字(5个)struct:结构体声明union:共用体声明enum:枚举声明typedef:声明类型别名sizeof:得到特定类型或特定类型变量的大小D存储级别关键字(6个)auto:指定为自动变量,由编译器自动分配及释放。

通常在栈上分配static:指定为静态变量,分配在静态变量区,修饰函数时,指定函数作用域为文件内部register:指定为寄存器变量,建议编译器将变量存储到寄存器中使用,也可以修饰函数形参,建议编译器通过寄存器而不是堆栈传递参数extern:指定对应变量为外部变量,即在另外的目标文件中定义,可以认为是约定由另外文件声明的韵蟮囊桓觥耙谩?const:与volatile合称“cv特性”,指定变量不可被当前线程/进程改变(但有可能被系统或其他线程/进程改变)volatile:与const合称“cv特性”,指定变量的值有可能会被系统或其他进程/线程改变,强制编译器每次从内存中取得该变量的值2流程控制关键字A跳转结构(4个)return:用在函数体中,返回特定值(或者是void值,即不返回值)continue:结束当前循环,开始下一轮循环break:跳出当前循环或switch结构goto:无条件跳转语句B分支结构(5个)if:条件语句else:条件语句否定分支(与if连用)switch:开关语句(多重分支语句)case:开关语句中的分支标记default:开关语句中的“其他”分治,可选。

C++中enum的用法

C++中enum的用法

1、枚举enum的用途浅例写程序时,我们常常需要为某个对象关联一组可选alternative属性.例如,学生的成绩分A,B,C,D等,天气分sunny, cloudy, rainy等等。

更常见的,打开一个文件可能有三种状态:input, output和append. 典型做法是,对应定义3个常数,即:const int input = 1;const int output = 2;const int append = 3;然后,调用以下函数:bool open_file(string file_name, int open_mode);比如,open_file("Phenix_and_the_Crane", append);这种做法比较简单,但存在许多缺点,主要的一点就是无法限制传递给open_file函数的第2个参数的取值范围,只要传递int类型的值都是合法的。

(当然,这样的情况下的应对措施就是在open_file函数内部判断第二个参数的取值,只有在1,2,3范围内才处理。

) 使用枚举能在一定程度上减轻这种尴尬(注1),它不但能实现类似于之前定义三个常量的功能,还能够将这三个值组合起来成为独一无二的组。

例如:enum open_modes {input = 1, output, append};以上定义了open_modes为枚举类型enumeration type。

每一个命名了的枚举都是唯一的类型,是一个类型标示器type specifier。

例如,我们可以重新写一个open_file函数: bool open_file(string file_name, open_modes om);在open_modes枚举中,input, output, append称为枚举子enumerator, 它们限定了open_modes定义的对象的取值范围。

这个时候,调用open_file函数和之前的方法还是一模一样:open_file("Phenix_and_the_Crane", append);但是,如果传递给open_file的第二个参数不是open_modes枚举类型值的话(注1),那么编译器就会识别出错误;就算该参数取值等价于input, output, append中的某个,也一样会出错哦!例如:open_file("Phenix_and_the_Crane", 1);2、枚举的定义一个枚举是一个类型,可以保存一组由用户刻画的值。

USB host 工作流程

USB host 工作流程

USB枚举步骤USB协议定义了设备的6种状态,仅在枚举过程种,设备就经历了4个状态的迁移:上电状态(Powered),默认状态(Default),地址状态(Address)和配置状态(Configured)(其他两种是连接状态(Attached)和挂起状态(Suspend))。

Attached和Powered状态不难理解:当一个设备被正确插入到主机的USB接口时,就处于Attached(连接)的状态。

设备连接好了,USB主机识别了设备,同时没有对设备进行请求,USB 设备就处于Suspended(挂起)状态.下面步骤是Windows系统下典型的枚举过程,但是固件不能依此就认为所有的枚举操作都是按照这样一个流程行进。

设备必须在任何时候都能正确处理所有的主机请求.1. 用户把USB设备插入USB端口或给系统启动时设备上电这里指的USB端口指的是主机下的根hub或主机下行端口上的hub端口。

Hub给端口供电,连接着的设备处于上电状态。

2. Hub监测它各个端口数据线上(D+/D-)的电压在hub端,数据线D+和D-都有一个阻值在14.25k到24.8k的下拉电阻Rpd,而在设备端,D+(全速,高速)和D-(低速)上有一个1.5k的上拉电阻Rpu。

当设备插入到hub端口时,有上拉电阻的一根数据线被拉高到幅值的90%的电压(大致是3V)。

hub检测到它的一根数据线是高电平,就认为是有设备插入,并能根据是D+还是D-被拉高来判断到底是什么设备(全速/低速)插入端口(全速、高速设备的区分在后面的章节中描述)。

检测到设备后,hub继续给设备供电,但并不急于与设备进行USB传输。

3. Host了解连接的设备每个hub利用它自己的中断端点向主机报告它的各个端口的状态(对于这个过程,设备是看不到的,也不必关心),报告的内容只是hub端口的设备连接/断开的事件。

如果有连接/断开事件发生,那么host会发送一个Get_Port_Status请求(request)以了解更多hub上的信息。

C语言枚举类型详解

C语言枚举类型详解

C语言详解- 枚举类型注:以下全部代码的执行环境为VC++ 6.0在程序中,可能需要为某些整数定义一个别名,我们可以利用预处理指令#define来完成这项工作,您的代码可能是:#define MON 1#define TUE 2#define WED 3#define THU 4#define FRI 5#define SAT 6#define SUN 7在此,我们定义一种新的数据类型,希望它能完成同样的工作。

这种新的数据类型叫枚举型。

1. 定义一种新的数据类型- 枚举型以下代码定义了这种新的数据类型- 枚举型enum DAY{MON=1, TUE, WED, THU, FRI, SAT, SUN};(1) 枚举型是一个集合,集合中的元素(枚举成员)是一些命名的整型常量,元素之间用逗号,隔开。

(2) DAY是一个标识符,可以看成这个集合的名字,是一个可选项,即是可有可无的项。

(3) 第一个枚举成员的默认值为整型的0,后续枚举成员的值在前一个成员上加1。

(4) 可以人为设定枚举成员的值,从而自定义某个范围内的整数。

(5) 枚举型是预处理指令#define的替代。

(6) 类型定义以分号;结束。

2. 使用枚举类型对变量进行声明新的数据类型定义完成后,它就可以使用了。

我们已经见过最基本的数据类型,如:整型int, 单精度浮点型float, 双精度浮点型double, 字符型char, 短整型short等等。

用这些基本数据类型声明变量通常是这样:char a; //变量a的类型均为字符型charchar letter;int x,y,z; //变量x,y和z的类型均为整型intint number;double m, n;double result; //变量result的类型为双精度浮点型double既然枚举也是一种数据类型,那么它和基本数据类型一样也可以对变量进行声明。

方法一:枚举类型的定义和变量的声明分开enum DAY{MON=1, TUE, WED, THU, FRI, SAT, SUN};enum DAY yesterday;enum DAY today;enum DAY tomorrow; //变量tomorrow的类型为枚举型enum DAYenum DAY good_day, bad_day; //变量good_day和bad_day的类型均为枚举型enum DAY方法二:类型定义与变量声明同时进行:enum //跟第一个定义不同的是,此处的标号DAY省略,这是允许的。

sizeof函数用法

sizeof函数用法

sizeof函数用法摘要:一、sizeof 函数简介1.sizeof 函数的作用2.数据类型长度3.函数原型二、sizeof 函数用法1.用法一:计算数组大小2.用法二:计算字符串长度3.用法三:计算结构体大小4.用法四:计算联合体大小5.用法五:计算枚举类型大小三、sizeof 函数注意事项1.不可用于判断数组越界2.不可用于判断字符串结束符3.结果与编译器相关正文:sizeof 函数是C 语言中一个非常常用的函数,它的主要作用是计算数据类型的大小。

在计算机中,每个数据类型都有其固定的长度,比如int 类型通常是4 字节,char 类型通常是1 字节。

sizeof 函数就是用来获取这些数据类型的大小的。

sizeof 函数的原型为:`size_t sizeof(类型名)`。

其中,`size_t`是一个与平台相关的类型,表示数据类型的大小。

在32 位系统中,`size_t`通常是`int`类型,而在64 位系统中,`size_t`通常是`long`类型。

sizeof 函数的用法有很多,下面我们来详细了解一下:1.用法一:计算数组大小当我们需要知道数组的大小时,可以使用sizeof 函数。

比如,有一个字符数组`char arr[10]`,我们可以使用`sizeof(arr)`来计算数组的大小。

需要注意的是,这里计算的是数组本身的大小,而不是数组中元素的大小。

2.用法二:计算字符串长度在C 语言中,字符串是以字符数组的形式存储的,通常会在字符串的结尾加上一个空字符("0")作为字符串的结束标志。

当我们需要知道字符串的长度时,可以使用sizeof 函数。

比如,有一个字符串`char str[] = "hello"`,我们可以使用`sizeof(str) - 1`来计算字符串的长度。

注意要减去1,因为空字符不计入字符串长度。

3.用法三:计算结构体大小当我们需要知道结构体的大小时,可以使用sizeof 函数。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

至从C语言开始enum类型就被作为用户自定义分类有限集合常量的方法被引入到了语言当中,而且一度成为C++中定义编译期常量的唯一方法(后来在类中引入了静态整型常量)。

根据上面对enum类型的描述,有以下几个问题:1.到底enum所定义出来的类型是一个什么样的类型呢?2.作为一个用户自定义的类型其所占用的内存空间是多少呢?3.使用enum类型是否真的能够起到有限集合常量的边界约束呢?4.大家可能都知道enum类型和int类型具有隐示(自动)转换的规则,那么是否真的在任何地方都可以使用enum类型的变量来代替int类型的变量呢?1. 到底enum所定义出来的类型是一个什么样的类型呢?在C++中大家都知道仅仅有两种大的类型分类:POD类型(注(1))和类类型。

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来进行引用。

注(1)POD类型:你可以将POD 类型看作是一种来自外太空的用绿色保护层包装的数据类型,POD 意为“Plain Old Data”(译者:如果一定要译成中文,那就叫“彻头彻尾的老数据”怎么样!)这就是POD 类型的含义。

其确切定义相当粗糙(参见C++ ISO 标准),其基本意思是POD 类型包含与C 兼容的原始数据。

例如,结构和整型是POD 类型,但带有构造函数或虚拟函数的类则不是。

POD 类型没有虚拟函数,基类,用户定义的构造函数,拷贝构造,赋值操作符或析构函数。

为了将POD 类型概念化,你可以通过拷贝其比特来拷贝它们。

此外,POD 类型可以是非初始化的。

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函数清理了过多的地址空间,从而破坏了外围函数的栈指针的指向,从而必然会导致程序运行时错误。

由上面的说明枚举类型有那么多的缺点,那我们怎样才能够有一个类型安全的枚举类型呢?实际上,在最新的C++0x 标准草案中有关于枚举作用域问题的提案,但最终的解决方案会是怎样的就无法未卜先知了,毕竟对于象C++ 这样使用广泛的语言来说,任何特性的增删和修改都必须十分小心谨慎。

当然,我们可以使用一些迂回的方法来解决这个问题(C++ 总是能给我们很多惊喜和意外)。

例如,我们可以把枚举值放在一个结构里,并使用运算符重载来逼近枚举的特性:struct FileAccess {enum __Enum {Read = 0x1,Write = 0x2};__Enum _value; // 枚举值FileAccess(int value = 0) : _value((__Enum)value) {}FileAccess& operator=(int value) {this->_value = (__Enum)value;return *this;}operator int() const {return this->_value;}};我们现在可以按照希望的方式使用这个枚举类型:FileAccess access = FileAccess::Read;并且,因为我们提供了到int 类型的转换运算符,因此在需要int 的地方都可以使用它,例如switch 语句:switch (access) {case FileAccess::Read:break;case FileAccess::Write:break;}当然我们不愿意每次都手工编写这样的结构。

通过使用宏,我们可以很容易做到这一点:#define DECLARE_ENUM(E) \struct E \{ \public: \E(int value = 0) : _value((__Enum)value) { \} \E& operator=(int value) { \this->_value = (__Enum)value; \return *this; \} \operator int() const { \return this->_value; \} \\enum __Enum {#define END_ENUM() \}; \\private: \__Enum _value; \};我们现在可以按如下的方式定义前面的枚举,并且不比直接写enum 复杂多少。

DECLARE_ENUM(FileAccess)Read = 0x1,Write = 0x2,END_ENUM()DECLARE_ENUM(FileShare)Read = 0x1,Write = 0x2,END_ENUM()。

相关文档
最新文档