Define与Const的使用

文章起因:


由于本人在项目中一直不清楚什么时候使用define  定义常量,什么时候使用宏,来定
义一些字符串啊,数字啊这些变量,所以就有了这篇文章的所在

首先两者的定义与实现

一.define(宏定义)
#define语法称之为预处理命令。#define声明主要用于将常量(或字符串)赋予有意义的名字,比如当你在编写一个日历程序时,可以定义:

#define MONTHS_PER_YEAR 12
Tips:
     1.通常情况下,习惯将预处理的常量名全大写,单词之间用下划线隔开
(与正常变量区分)。
     2.如果是定义常量,若这个常量的适用范围局限于.m,那么习惯性在常量名前
加k,若常量在类之外可见,则通常以类名为前缀

预处理代码起的作用实际上相当于在编译之前!!!
预处理代码起的作用实际上相当于在编译之前!!!
预处理代码起的作用实际上相当于在编译之前!!!
重要事情说三遍。也就是说宏使用过多会增加编译时间,

而一个常量在栈中开辟空间是很高效的。

在整个代码中进行了一次“搜索、替换”功能.通常情况下不管是声名字符串还是函数其作用主要有两个:
个人认为使用宏有一下好处:

1.增强代码可读性
2.方便全局使用和修改一些方法和参数
3.增强复用性


(以上为个人总结,标准答案见第二大标题:两者的区别 中的那篇引文博客)


二.const(定义常量)
const 如果是声明常量,仅仅是想要在.m文件中使用,那么一定要同时使用static 和const来声明,若不加系统在编译时会自动为它加一个extern (外部符号),此时,若另一个编译单元出现了同名变量就会报错,并且很难查找错误

只能在警告区找到
但无法确认错误位置

这是OC程序员最不愿意看到的错误。。。也是很难查找的错误,跟修改已经创建的类的文件名的错误差不多。

结合经验,和在网上查找资料,我个人认为,可以得出以下结论:

  1. 多用类型常量,少用#define预处理指令(出自《Effective Objective-C》第四条原则)

2.苹果的API中,大多数字符串,也是用以下这种方式(如以Key,style,Type结尾的一些参数)

// Constants.h
FOUNDATION_EXPORT NSString *const MyFirstConstant;
FOUNDATION_EXPORT NSString *const MySecondConstant;
//etc.
// Constants.m
NSString *const MyFirstConstant = @"FirstConstant";
NSString *const MySecondConstant = @"SecondConstant";

或者

extern NSString * const PPRememberMusicList;
extern NSString * const PPLoadMusicAtListLoad;
extern NSString * const PPAfterPlayingMusic;
extern NSString * const PPGotoStartupAfterPlaying;
NSString * const PPRememberMusicList = @"Remember Music List";
NSString * const PPLoadMusicAtListLoad = @"Load music when loading list";
NSString * const PPAfterPlayingMusic = @"After playing music";
NSString * const PPGotoStartupAfterPlaying = @"Go to startup pos. after playing";

两者的区别


网上有关于C++这两个关键字的说明,看文章格式格式应该是来自于C++的一个本书中的,感觉写的相当详细:
来自:@奮 鬥@的专栏
const常量与define宏定义的区别
因为C++和OC本来就是来自于C所以这里可以直接参考的。

其中本人筛选了其中比较重要的一些比较,是有利于解决本文的初衷问题的:

  1. const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是象#define一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一份拷贝(因为是全局的只读变量,存在静态区),而 #define定义的常量在内存中有若干个拷贝
    归纳为:使用const定义常量比较好,因为省内存空间
  2. 提高了效率。 编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高
    归纳为:使用const定义常量比较好,因为效率高
  3. 宏替换只作替换,不做计算,不做表达式求解;
    宏预编译时就替换了,程序运行时,并不分配内存。
    归纳为:宏定义 定义函数式比较好,因为省内存
    还有这一段:
const 与 #define的比较
 C++ 语言可以用const来定义常量,也可以用
#define来定义常量。但是前者比后者有更多的优点:

(1) const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误(边际效应)。

(2) 有些集成化的调试工具可以对const常量进行调试,但是不能对宏常量进行调试。

l 【规则5-2-1】在C++ 程序中只使用const常量而不使用宏常量,即const常量完全取代宏常量。
归纳为:const就是比宏牛逼!!!!!(哈哈 常量来说,并不是宏就没用了)

总结问题答案

看到这里问题的答案其实已经很清楚了,而且也解决了这个问题之外的一些问题的答案,让我对C++和内存优化问题上有了进一步的了解!!!

 专业总结一万年
 const简介:之前常用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽成宏,推荐我们
使用const常量。

编译时刻:宏是预编译(编译之前处理),const是编译阶段。
编译检查:宏不做检查,不会报编译错误,只是替换,const会编译检查,会报编译错误。
宏的好处:宏能定义一些函数,方法。 const不能。
宏的坏处:使用大量宏,容易造成编译时间久,每次都需要重新替换。


2018-6-22 1:50

番外篇

const、static与extern

上面大量讲了constdefine这两个关键字的作用与区别,分析有些片面。
比如const在修饰一个变量如NSString字符串的时候,是将这个字符串放在栈区,随应用声明周期,因为常量是放在栈区由系统直接分配管理的。

之所以为什么要考虑一个变量的内存问题呢?其实程序员每天在做的工作不仅仅是完成一个代码的编写,更多的是在做一个整体的把控。如何从一个思想到一个能够为人服务的手机软件?
这期间经历的什么其实需要我们考量的。这个些问题我会在一片文章中详谈!我觉得作为一个智者,应该搞清楚自己知道什么不知道什么,才利于前行!


         ---------致敬那曾经的‘伪程序员’-------自己!-------

const

const 在修饰一份变量的时候,一最简单的理解方式就是,老师拿了一个动物大象模型,给同学讲故事,这个动物的模型将在整个故事过程中充当学生脑海里整个听故事过程中的这个大象,而大象只有一个,在过程中它是不可能被替换的,因为它真实存在,而大象经历了什么,又代表什么是任务设定的,这个是可以定义的;而这个大象它代表了什么将会在这个古故事结束之后,任由他去了。也许他仅仅是个模型,但是,只要在这个故事当中,他就是不可代替的!

所以,一个常量的生命周期就如同显示存在的一个事物,不可被替代的事物,独一无二的事物(如太阳,月亮和星星)也正对应了----常这个字!
不知道说道这里,和我一样经历的你有没有明白些什么!

它随时被申请在内存空间,但永远只有一份!也正是为什么一个程序中,声明两个相同的const常量,会出现上面报错的原因!

static

举一反三,我们可以从字面理解,“静”这个字的含义,之所以是静态,专业术语分析是因为,专门用来修饰局部变量,(因为局部变量是在函数结束的时候就会消失掉),将局部变量的生命周期变为和全局变量的生命周期一样,在程序结束的时候消失!

 #专业总结
* 修饰局部变量
* 让局部变量只初始化一次
* 局部变量在程序中只有一份内存
* 并不会改变局部变量的作用域,仅仅是改变了局部变量的生命周期(只到程序结束,这个局
部变量才会销毁)
* 修饰全局变量

* 全局变量的作用域仅限于当前文件

extern

更容易理解在这里不再复述!

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

推荐阅读更多精彩内容