如何正确使用const(常量),define(宏)
前言
在开发中,也许我们会经常使用到宏定义,或者用const修饰一些数据类型,经常有开发者不知道怎么正确使用,导致项目中乱用宏定义与const修饰符。本篇主要介绍在开发中怎么正确使用const与define(宏定义)
当我们想定义全局共用的一些数据时,比如通知名字,动画时长等等,我们可以用宏、常量、变量:
宏:
// 注意后面不需要带符号
#define ScottDidLoginSuccess @"登陆成功"
变量:
// 注意后面一定要带符号
NSString *scottDidLoginSuccess = @"登陆成功";
常量:
// 四种写法
static const NSString *scottDidLoginSuccess = @"登陆成功";
const NSString *scottDidLoginSuccess = @"登陆成功";
NSString const *scottDidLoginSuccess = @"登陆成功";
NSString *const scottDidLoginSuccess = @"登陆成功";
那么问题来了,我们到底该如何选择呢?
让我来先将一下我对它们之间的理解吧:
- 宏:只是在预处理阶段进行文本替换,没有类型,不做任何类型检查,编译器可以对相同的字符串进行优化,只保存一份到数据段。甚至有相同后缀的字符串也可以优化,你可以使用GCC编译测试,
Hello world与world两个字符串,只存储前面一个。取的时候只需要给前面和中间的地址,如果是整型、浮点型会有多分拷贝,但这些数写在指令中,占的只是代码片段而且,大量使用宏会导致二进制文件变大。 - 变量:共享一块内存空间,就算项目中N处用到,也不会分配N块内存空间,可以被修改,在编译阶段做类型检查。
- 常量:共享一块内存空间,就算项目中N处用到,也不会分配N块内存空间,可以根据
const修饰的位置设定能够修改,在编译阶段做类型检查。
常量区分
全局常量:不管你定义在任何文件夹,外部都能访问
const NSString *scottDidLoginSuccess = @"登陆成功";
局部常量:用static修饰后,不能供外界访问
static const NSString *scottDidLoginSuccess = @"登陆成功";
const修饰位置不同,代表什么
// 1.
const NSString *scottDidLoginSuccess = @"登陆成功";
// 2.
NSString const *scottDidLoginSuccess = @"登陆成功";
// 3.
NSString * const scottDidLoginSuccess = @"登陆成功";
咋一看,WTF,这不都张一样嘛,其实不一样,下面解释一下各代表什么
*scottDidLoginSuccess不能被修改,scottDidLoginSuccess能被修改*scottDidLoginSuccess不能被修改,scottDidLoginSuccess能被修改,也就是和第一种情况是一样的scottDidLoginSuccess不能被修改,*scottDidLoginSuccess能被修改。
结论:const右边的总不能被修改
所以我们一般定义一个常量又不想被修改,应该这样定义:
NSString *const scottDidLoginSuccess = @"登陆成功";
两者之间的区别
define在预处理阶段进行替换,const常量在编译阶段使用;define不做类型检查,只进行替换,const常量有数据类型,会执行类型检查;define不能调试,const常量可以调试;define定义的常量在替换后运行过程中,会不断占用内存,而const定义的常量存储在数据段,只有一份拷贝,效率更高;define可以定义函数,const不可以。
如何正确使用const(常量),define(宏)的更多相关文章
- 面试问题5:const 与 define 宏定义之间的区别
问题描述:const 与 define 宏定义之间的区别 (1) 编译器处理方式不同 define宏是在预处理阶段展开: const常量是编译运行阶段使用: (2) 类型和安全检查不同 ...
- const与#define宏常量 , inline与#define
1.预处理 预处理器是在真正的编译开始之前由编译器调用的独立程序.预处理器可以删除注释.包含其他文件以及执行宏替代. 预处理命令(宏定义#define..#undef. 文件包含#include. 条 ...
- 关于const和define的内存分配问题的总结
关于const和define的内存分配问题 const与#define宏定义的区别----C语言深度剖析 1, const定义的只读变量在程序运行过程中只有一份拷贝(因为它是全局的只读变量,存放在静 ...
- C++笔记020:const 和 #define 的对比
原创笔记,转载请注明出处! 点击[关注],关注也是一种美德~ 第一,const与#define的相同点 C++中的const常量类似于宏定义 const int c = 5 ≍ #defi ...
- 正确使用iOS常量(const)、enum以及宏(#define)
前言:本文主要梳理iOS中如何使用常量.enum.宏,以及各自的使用场景. 重要的事情首先说:在iOS开发中请尽量多使用const.enum来代替宏定义(#define):随着项目工程的逐渐增大,过多 ...
- #define宏常量和const常量的区别
C++ 语言可以用const 来定义常量,也可以用#define 来定义常量.但是前者比后者有更多的优点:(1) const 常量有数据类型,而宏常量没有数据类型.编译器可以对前者进行类型安全检查.而 ...
- iOS define 宏定义 和 const定义常量区别
const const 是c++中的修饰符. c++中常用来定义常量,修饰左值. #define 宏定义语句, 在预处理阶段直接做文本替换,不做类型检查. 它们之间的最大区别: 1. 对于co ...
- const常量与define宏定义的区别(转)
#define RADIUS 100; const float RADIUS = 100; (1) 编译器处理方式不同 define宏是在预处理阶段展开. const常量是编译运行阶段使用. ( ...
- const和#define常量的区别
(1) 编译器处理方式不同 define宏是在预处理阶段展开. const常量是编译运行阶段使用. (2) 类型和安全检查不同 define宏没有类型,不做任何类型检查,仅仅是展开. const常量有 ...
随机推荐
- Python 爬虫-豆瓣读书
import requests from bs4 import BeautifulSoup def parse_html(num): headers = { 'User-Agent': 'Mozill ...
- Python 两种方式实现斐波那契数列
斐波那契数列指的是这样一个数列 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10946 ...
- postman与charles的结合使用
1.准备charles环境 Charles端口一般配置的为8888,不知道怎么配置详见charles文档 打开charles,发现访问浏览器任意页面都是失败. 在浏览器的高级设置中设置代理服务器,以火 ...
- 如何在乌班图上配置java开发环境
不想说的那么细,每条命令都说一下,在现在这个浮躁的时代,很少有人能看的下去,我就直接上命令,最简单的快捷的方式. 1:安装软件 2:设置root密码 3:配置mysql远程登录 4:安装java运行环 ...
- CodeBlocks X64 SVN 编译版
CodeBlocks X64 SVN 编译版 采用官方最新的SVN源码编译而来,纯64位的,所以32位系统是不能使用的.字体使用的是微软的YaHei UI字体,如果有更好的字节建议,可以留言. 由于直 ...
- Eclipse中安装svn的插件安装和使用
先关闭Eclipse 步骤一:下载site-1.10.11.zip 将其解压 解压后目录 步骤二:创建一个文件夹svn,将解压后的文件copy到svn路径下 步骤三:打开Eclipse安装路径: e ...
- 【bzoj1856】[Scoi2010]字符串 Catalan数
题目描述 lxhgww最近接到了一个生成字符串的任务,任务需要他把n个1和m个0组成字符串,但是任务还要求在组成的字符串中,在任意的前k个字符中,1的个数不能少于0的个数.现在lxhgww想要知道满足 ...
- HDU - 2814 Visible Trees
题意: m*n(1<=m,n<=100000)的森林里,起始点在(1,1),某人从(0,0)点开始看,问能看到多少棵树. 题解: 求出1~x中的每个数与1~y的数中互质的数的总和.用素数筛 ...
- bzoj4386 Wycieczki
题目描述 给定一张n个点m条边的带权有向图,每条边的边权只可能是1,2,3中的一种.将所有可能的路径按路径长度排序,请输出第k小的路径的长度,注意路径不一定是简单路径,即可以重复走同一个点. 输入 第 ...
- 做一个类似JQuery获取DOM对象的$()
在dom操作时,有时根据id获取单个对象.有时根据className获取多个对象.平常可能我们用两个函数来实现这两个功能.不过我将它们整合了一下,目前使用情况良好,函数如下: view source ...