define与enum与const 您所在的位置:网站首页 枚举类型定义花括号中的标识符称为 define与enum与const

define与enum与const

2023-08-21 17:45| 来源: 网络整理| 查看: 265

enum枚举类型

只能定义整型(字符型ascII码)

  一般的定义方式如下:

enum enum_type_name { ENUM_CONST_1, ENUM_CONST_2, ... ENUM_CONST_n } enum_variable_name;   注意:enum_type_name 是自定义的一种数据类型名,而 enum_variable_name 为enum_type_name类型的一个变量,也就是我们平时常说的枚举变量。实际上enum_type_name类型是对一个变量取值范围的限定,而花括号内是它的取值范围,即 enum_type_name 类型的变量 enum_variable_name 只能取值为花括号内的任何一个值,如果赋给该类型变量的值不在列表中,则会报错或者警告。

ENUM_CONST_1、ENUM_CONST_2、...、ENUM_CONST_n,

这些成员都是常量,也就是我们平时所说的枚举常量(常量一般用大写)。 enum 变量类型还可以给其中的常量符号赋值,如果不赋值则会从被赋初值的那个常量开始 依次加 1,如果都没有赋值,它们的值从 0 开始依次递增 1。

  这里还有当花括号内的常量中有个被赋值(非顺序默认值时)后面的枚举常量(后面不再有被赋值时)会在此值上依次加1,直到下一个被赋值的常量.

eg:

例如下列中

enum weekday{sun,sss=100,ddd,mon=10,tue,wed,thu,fri,sat};

sun值为1,ddd为101,tue为11,依次,sat为15。

  还有当枚举常量中插入新的常量时重新打乱默认赋值重新从赋值处往后依次加1。

  sizeof(weekday)值是4。

  enum变量占用的空间与编译器相关。

  数编译器默认enum型长度等于int型,很多人也把enum型变量等同于int,但C标准:“枚举型尺寸是能够容纳最大枚举子值的整数尺寸”,“枚举类型中枚举子的值必须要能用一个int型表述”。也就是说,枚举型的尺寸不能超过int型,但不必等于int型,只要能容纳最大枚举子就行。

  define宏

  在C或C++源程序中允许用一个标识符来表示一个字符串,称为“宏”。被定义为“宏”的标识符称为“宏名”。在编译预处理时,对程序中所有出现的“宏名”,都用宏定义中的字符串去代换,这称为“宏代换”或“宏展开”。宏定义是由源程序中的宏定义命令完成的。宏代换是由预处理程序自动完成的。

  在C或C++语言中,“宏”分为有参数和无参数两种。

  1. 无参宏定义

  无参宏的宏名后不带参数。其定义的一般形式为:

        #define 标识符 字符串

  其中的“#”表示这是一条预处理命令。凡是以“#”开头的均为预处理命令。“define”为宏定义命令。“标识符”为所定义的宏名。“字符串”可以是常数、表达式、格式串等。

  说明:

  1. 宏定义是用宏名来表示一个字符串,在宏展开时又以该字符串取代宏名,这只是一种简单的代换,字符串中可以含任何字符,可以是常数,也可以是表达式,预处理程序对它不作任何检查。如有错误,只能在编译已被宏展开后的源程序时发现。   2. 宏定义不是说明或语句,在行末不必加分号,如加上分号则连分号也一起置换。

  3. 宏定义必须写在函数之外,其作用域为宏定义命令起到源程序结束。如要终止其作用域可使用#undef命令。

  2.带参定义

   c语言允许宏带有参数。在宏定义中的参数称为形式参数,在宏调用中的参数称为实际参数。对带参数的宏,在调用中,不仅要宏展开,而且要用实参去代换形参。

    带参宏定义的一般形式为:

    #define 宏名(形参表) 字符串

  const

  const 修饰的只读变量必须在定义的同时初始化

  节省空间,避免不必要的内存分配,同时提高效率。编译器通常不为普通 const 只读变量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的值,没有了存储与读内存的操作,使得它的效率也很高。

eg:

#define M 3 //宏常量 const int N=5; //此时并未将 N 放入内存中 ...... int i=N; //此时为 N 分配内存,以后不再分配! int I=M; //预编译期间进行宏替换,分配内存 int j=N; //没有内存分配 int J=M; //再进行宏替换,又一次分配内存! const 定义的只读变量从汇编的角度来看,只是给出了对应的内存地址,而不是象#define一样给出的是立即数,所以,const 定义的只读变量在程序运行过程中只有一份拷贝(因为它是全局的只读变量,存放在静态区)。

而#define 定义的宏常量在内存中有若干个拷贝。

#define 宏是在预编译阶段进行替换,而 const 修饰的只读变量是在编译的时候确定其值。

#define 宏没有类型,而 const 修饰的只读变量具有特定的类型。

  1、修饰一般变量

eg:

  int const i=2; 

  或

  const int i=2;

  2、修饰数组

eg:

  int const a[5]={1,2,3,4,5};

  或   const int a[5]={1,2,3,4,5};

3.修饰指针

eg:

const int *p; // p 可变,p 指向的对象不可变 int const *p; // p 可变,p 指向的对象不可变 int *const p; // p 不可变,p 指向的对象可变 const int*const p; //指针 p 和 p 指向的对象都不可变

4、修饰函数的参数

eg:

  void Fun(const int i);

5、修饰函数的返回值

eg:

   const int Fun(void);

在另一连接文件中引用 const 只读变量:   extern const int i;   //正确的声明   extern const int j = 10;   //错误!只读变量的值不能改变。

  enum优点

  1、内部代码使用enum类型优于define,对外API接口尽量避免用enum型。    2、enum型用于定义常量集合,相比#define有一些优势。如:enum是一种数据类型,使用时会检查类型匹配; enum增加了范围约束,避免变量赋值和使用时超出定义范围。   3、用enum关键字说明常量使程序更容易维护,并且能防止给不同的常量赋予相同的值。使程序调试起来更方便,因为某些标识符调试程序能打印枚举常量的值。这一点在调试程序时是非常用的,因为如果你的程序在使用枚举常量的一行语句中停住了,你就能马上检查出这个常量的值;反之,绝大多数调试程序无法打印标识符常量的值,因此你不得不在头文件中手工检查该常量的值。   4、枚举和define都可以swtich,枚举是类型安全的 define不是类型安全的,枚举只能定义整形值,define能定义几乎任何值    5、宏和枚举之间的差别主要在作用的时期和存储的形式不同,宏是在预处理的阶段进行替换工作的,它替换代码段的文本,程序运行的过程中宏已不存在了。而枚举是在程序运行之后才起作用的,枚举常量存储在数据段的静态存储区里。宏占用代码段的空间,而枚举除了占用空间,还消耗CPU资源。

  define优点

   非关键字

   当在程序中想要修改某一个值得时候,而且这个值又在很多地方引用。这时候就能体现出宏定义的强大优点了。

   利用define来定义 字符串宏常量,除了定义宏常数之外,经常还用来定义字符串,尤其是路径:

   用define 宏定义 注释符号

  缺点:

(1) 无法对宏定义中的变量进行类型检查 

  此缺点,是相对于const变量来说的 

[define与const的区别的简单总结]   define定义的变量,是Compile-Time时期的变量,系统在编译时候,就将其全部替换,而不会对其变量进行类型等属性检查,相对不是很安全,可能存在潜在的问题,而没有发现. 正因为其仅仅是编译时期替换,所以其定义的变量,是不会在运行时候分配内存的,不占用内存空间.    const定义的变量,是 Run-Time时期的变量,如果类型不匹配,系统在运行时候,就会发现并提示或报错,对应的,const变量在运行时期,也是一种变量,系统会为其分配内存.  (2) 边界效应  未加括号带来的边界效应  由于宏定义的时候,其各个分量未加括号,而在使用宏定义的时候,传递的参数是变量的表达式,然后经过系统展开后,由于优先级的原因,导致其结果不是你所希望的. 

  const优点

  利用define来定义数值类型的数据,一般只是用来定义常量 ,如果要定义一些变量,则可以使用c语言中const这个关键字。   我们已经讨论了const 这个关键字,我们知道const 修饰的数据是有类型的,而define 宏定义的数据没有类型。为了安全,我建议你以后在定义一些宏常数的时候用const代替,编译器会给const 修饰的只读变量做类型校验,减少错误的可能。

  

第一:#define定义了一个宏,在编译之前(预编译)就会被替换掉, 宏不做检查,只是替换,并且在字符替换可能会产生意料不到的错误(边际效应);  而const常量有具体的类型,在编译阶段会执行类型检查,当试图去修改该变量的时候,编译器会报错。

第二:#define可以定义函数,如: #define redcolor [UIColor redColor]  , 而const不能。

第三: #define定义的缺点是:如果大量使用,容易造成编译时间久,每次预编译的时候,都会进行替换操作

第四:#define在预编译阶段不会分配内存,在预编译之后,当有变量调用这个宏的时候,会分配一份内存,而const常量会在内存中分配(可以是堆中也可以是栈中)。具体可以参考第五条的解释

第五:const  可以节省空间,避免不必要的内存分配。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有