const 、enum 和#define 的区别

      刚从事IOS这行的时候,const很少用,主要是用#define和enum,后来慢慢的注意到,如何提升代码的质量,如何从细节处优化产品的性能,这点是至关重要的,对于自己之前的理解和相关内容的探索,本文准备从这三者的定义以及差异处进行简单说明。

定义:

1) const:修饰的数据类型是指常类型,常类型的变量或对象的值是不能被修改的,类似于只读属性;  

关于const的一些常用的使用情况,如下所示:

常变量:

const 数据类型 符号常变量 = 数值 ,如:const float a=2.18;

指针常量:

数据类型 *const 指针变量=变量名,如:NSString* const p="abc";  const修饰的是指针变量,而不是指针的值,所以指针指向的值是可以修改的。

常指针:

const 数据类型 *指针变量=变量名,如 const char* a = @"jack"; 或者是,数据类型 const *指针变量=变量名,如 char* b = @"rose". 这是指针指向的值就是不可以改变的。

还有一种情况就是指针变量本身不可以修改,指针指向的值也是不允许修改的,就是指针常量和常指针组合,这种称为

常指针常量:

const 数据类型 *const 指针变量=变量名, 如const NSString* const c = @"jane"; 或数据类型 const *const 指针变量=变量名, 如NSString* const * const d = @"kangkang"

2) enmu (推荐NS_ENUM宏定义枚举)

enum是计算机编程语言中的一种数据类型。枚举类型:在实际问题中,有些变量的取值被限定在一个有限的范围内。例如,一个星期内只有七天,一年只有十二个月,一个班每周有六门课程等等。如果把这些量说明为整型,字符型或其它类型显然是不妥当的。为此,C语言提供了一种称为“枚举”的类型。在“枚举”类型的定义中列举出所有可能的取值,被说明为该“枚举”类型的变量取值不能超过定义的范围。应该说明的是,枚举类型是一种基本数据类型,而不是一种构造类型,因为它不能再分解为任何基本类型

3)#define

宏定义是用宏名来表示一个字符串,在宏展开时又以该字符串取代宏名,这只是一种简单的代换,字符串中可以含任何字符,可以是常数,也可以是表达式,预处理程序对它不作任何检查。如有错误,只能在编译已被宏展开后的源程序时发现


上面是对这三者简单定义的解释,有不周全之处,如需深入了解的,可以自己查看一些相关资料

差异:


1)关于const和#define,我自己理解的有如下几点:

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

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

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

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

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

 例如:#define PI 3.14159 //常量宏

const doulbe Pi=3.14159; //此时并未将Pi放入ROM中 ......

double i=Pi; //此时为Pi分配内存,以后不再分配!

double I=PI; //编译期间进行宏替换,分配内存

double j=Pi; //没有内存分配

double J=PI; //再进行宏替换,又一次分配内存!

const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是象#define一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一份拷贝,而 #define定义的常量在内存中有若干个拷贝。

简单的说就是:const只会在被调用的时候分配一次内存,二#define则是在宏替换的时候,每次都会被分配一次内存,比较费内存。

但是理论上来说,const不仅在运行时需要占用空间,而且还需要一个内存的引用,但从时间上来说,这些都是无关紧要的,编译器会对其进行优化。


所以如果定义字符串,字面量或者数字,更推荐使用static 方式声明变量,而不是#define,恰当的方法如下:

static NSString* const a = @"123";

static CGFloat b = 4.0;

不恰当的方法:

#define a @"123"

#define b 4.0

但是对于整型来说,替代#define的最好方法应该是enum,使用enum时,推荐使用最新的fixed underlying type 规范的NS_ENUM 和NS_OPTIONS,因为它们是给予C语言的枚举,保留了C语言的的简洁和简明的特色,

第一:IOS 中UITextBorderStyle (边框设置的枚举)

typedef NS_ENUM(NSInteger, UITextBorderStyle) {

UITextBorderStyleNone,

UITextBorderStyleLine,

UITextBorderStyleBezel,

UITextBorderStyleRoundedRect

}; 

下面一个是另一种方式(不推荐使用)

enum {

UITextBorderStyleNone,

UITextBorderStyleLine,

UITextBorderStyleBezel,

UITextBorderStyleRoundedRect

};

typedef  NSInteger  UITextBorderStyle;



第二:UIView 的 UIViewAnimationOptions (动画的枚举)

typedef NS_OPTIONS(NSUInteger, UIViewAnimationOptions) {

UIViewAnimationOptionLayoutSubviews            = 1 <<  0,

UIViewAnimationOptionAllowUserInteraction      = 1 <<  1, 

UIViewAnimationOptionBeginFromCurrentState    = 1 <<  2,

UIViewAnimationOptionRepeat                    = 1 <<  3, 

UIViewAnimationOptionAutoreverse              = 1 <<  4, 

UIViewAnimationOptionOverrideInheritedDuration = 1 <<  5,

UIViewAnimationOptionOverrideInheritedCurve    = 1 <<  6, 

UIViewAnimationOptionAllowAnimatedContent      = 1 <<  7, 

UIViewAnimationOptionShowHideTransitionViews  = 1 <<  8,

UIViewAnimationOptionOverrideInheritedOptions  = 1 <<  9, 

UIViewAnimationOptionCurveEaseInOut            = 0 << 16,

UIViewAnimationOptionCurveEaseIn              = 1 << 16,

UIViewAnimationOptionCurveEaseOut              = 2 << 16,

UIViewAnimationOptionCurveLinear              = 3 << 16,

UIViewAnimationOptionTransitionNone            = 0 << 20, // default

UIViewAnimationOptionTransitionFlipFromLeft    = 1 << 20,

UIViewAnimationOptionTransitionFlipFromRight  = 2 << 20,

UIViewAnimationOptionTransitionCurlUp          = 3 << 20,

UIViewAnimationOptionTransitionCurlDown        = 4 << 20,

UIViewAnimationOptionTransitionCrossDissolve  = 5 << 20,

UIViewAnimationOptionTransitionFlipFromTop    = 6 << 20,

UIViewAnimationOptionTransitionFlipFromBottom  = 7 << 20,

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容