extern四个根本字,正确使用const

  • extern四个根本字,正确使用const。全局变量:

暗中同意境况下,C语言的全局变量是大地都能够访谈的,也正是全局变量能够跨文件访谈。

基础知识:(参考Henry725的博客)

static

int age = 20; 短处:能修改,优点:内部存款和储蓄器中只保留一份,不会时有产生十分的多一时半刻间和空间间

extern能够援引全局变量

1、函数或变量在宣称时,并未给它实在的物理内部存款和储蓄器空间,它有的时候能够保险你的程序编写翻译通过,
不过当函数或变量定义的时候,它就在内部存款和储蓄器中有了实际上的物理空间。
2、要是您在编写翻译模块中援用的外表变量没有在整个工程中任何叁个地点定义的话,
那么固然它在编写翻译时能够透过,在三翻五次时也会报错,因为程序在内部存款和储蓄器中找不到这一个变量!
3、对于三个全部的主次,内部存款和储蓄器中的布满情况:
| 代码区 |
| 全局数据区 |
| 堆区 |
| 栈区 |

修饰局地变量

+ 宏:```objc#define age 20 优点:不可修改,缺点:会产生很多临时的内存空间

譬喻说,假如有三个大局变量int money = 100;
extern int money 意为:援引那一个全局变量,而非定义二个全局变量

1.extern

extern用于变量的扬言,告诉编写翻译器:已经存在一个全局变量,可是不在当前的编写翻译单元内,需求两次三番的时候在任何编写翻译单元中检索。

让部分变量只早先化二次

  • 常量:

注意:不允许出现七个变量名同样的全局变量
   函数和变量同样,都得以被全局引用

2.static

修更换量作用域为近期编写翻译单元,变量生命周期不改变;
幸免双重定义全局变量
2.2. 修饰局地变量 –
修更换量的生命周期为全方位工程周期,变量功效域不改变

有的变量在先后中唯有一份内部存款和储蓄器

static的作用:
static 修饰的全局变量功效域只限于当前文件
所以被static修饰的全局变量不可能被引述
static修饰的有的变量只会开端化二遍,在方方面面程序运转进程中始终存在

3.const

const修饰侧面的变量,用来限制变量为只读属性。

并不会改换部分变量的成效域,仅仅是改换了一些变量的生命周期(只到程序停止,那一个部分变量才会销毁)

const int age = 20;优点:不能修改只读,且内存中只会有一份存储空间 // 等价于 int const age = 20;

 const :
const只修饰它左侧的内容,被const修饰的内容都以常量、都以不能够再修改的

4.define

在先后的预编写翻译阶段进行替换管理。

修饰全局变量

  • 注意:

    亚州城ca88手机版 1Snip20150906_60.png亚州城ca88手机版 2Snip20150906_61.png亚州城ca88手机版 3Snip20150906_62.png

int * const p1;
p1是常量 *p1是变量

5. define与const

区别:
1.define宏是在预管理阶段进行。
const常量是编写翻译运转阶段选取。
2.define不做检查,不会报编写翻译错误,只是交替。const会编写翻译检查,会报编写翻译错误
3.define在开展的时候才分配内部存储器,展开三次分配三遍内存。const在概念的时候会分配三遍内部存款和储蓄器到静态区,使用时不另行分配
4.define方可定义一些简练的运算函数

全局变量的功能域只限于当前文件

二、 总结:

  • const:const只修饰它侧面的开始和结果,被const修饰的内容都是常量。

  • static:

    • 被static修饰的全局变量/常量,只限当前文件访问
    • 亚州城ca88手机版,被static修饰的片段变量,只会据有一块内部存款和储蓄器,整个程序运转不会销毁,只会初步化贰次。
  • extern:能够引用一个全局变量/常量

  • 常量使用潜准绳

    • 常量必须在编译时就必须有确定的值

extern四个根本字,正确使用const。int const * p1; 
*p1是常量 p1是变量
const  int *p1;

6. static和const的一块利用

宣称二个只读的静态变量

const

三、作用域

  • int money; 全局变量:

  • 默许景况下,全世界都以可以访谈的,不止限某二个类,利用extern能够援引叁个全局变量,如:extern
    int money;
    =>援引有些类的全局变量money。何况我们得以对全局变量money进行改变。

  • const int money ;

    • 暗许意况下,举世都得以用,但是不得用改,只读:extern const int
      money; =》 只读不可改。

    • 细心:类中等高校函授数也是:全世界都能够访谈的,我们只须求引用就可以调用。引用函数写法:extern
      void eat();

  • static int money;

    • 被static修饰的全局变量:效能域:只限制在现阶段文件中做客使用。
  • static int const money;

    • 被static修饰的全局常量:只限当前文件中选用,且不可改,只读

const int *const p1;
p1和 *p1都以常量
int const * const p1;

7. extern和const的一块儿利用

在八个文本中时常利用的同一个全局变量。
运用情形:
1、.h文件中声称

亚州城ca88手机版 4

Snip20170724_15.png

2、.m文件中赋值

亚州城ca88手机版 5

Snip20170724_16.png

3、pch文件中程导弹入头文件就能够在任何项目中探望

尚未const修饰的指针

四、 应用:

const int age = 20;
int *p = &age;
*p = 30;  不行

在swift想达成平等的作用非常轻松,只须要新建三个swift文件,定义常量就可以。

亚州城ca88手机版 6

Snip20170725_21.png

此处间接访谈就能够,都不要放到.pch文件中,因为默许权限是internal
public : 最大权力,能够在如今framework和任何framwork中拜候;
internal : 暗中认可权限,能够在时下framework中放肆拜访;
private : 私有权力,只可以在近年来文件中走访;

亚州城ca88手机版 7

Snip20170725_22.png

指针p和*p都能被改换

1. 字符串常量
// cellID 字符串被const 修饰了,,字符串类型的cellID不可改 NSString * const cellID = @"cellTagID"; // 注意:NSString字符串 == 一个指针指向它 int const *age = 10; // age 不可修改
  • 计算写法:const 和 变量 紧挨着防止不供给的荒唐

  • 常量使用潜准则

    • 常量必须在编译时就必须有确定的值

// 是错误的,因为[UIColor redColor] -> 是在运行时才确定的,不符合常量使用的潜规则UIColor *const JPGlobalColor = [UIColor redColor];// 宏定义正确#define JPGlobalColor [UIColor redColor]

 static :
 1> 被static修饰的全局变量\常量
    1) 只限于当前文件访问
    2) 改造了作用域
 2> 被static修饰的有的变量
    1) 只会占领一块内部存款和储蓄器,在一切程序运维过程都不会销毁,只会起始化壹遍
    2) 改换了生命周期,并未更改成效域
 
 extern : 能够引用二个全局变量\常量
默许全局变量若无用static修饰,全部都是可被extern的(即全局可访谈,但可被访问到的前提是:在别的地点访谈这么些全局变量必供给加extern修饰符,作者称之为可被extern)

8、用第7条代替define

一般常量的话,都用extern const 来取代define。
因为若是定义#define的办法,整个工程将被另行编写翻译,那样带来的日子浪费综上可得
当然了成千上万情景或许代表不了的,一般定义常量的时候是应当运用这种办法来定义,可是也只是常量宏不被引入,不过类函数宏用的依然很便利的,
const、#define的得失
编写翻译器能够对const举办项目安检。而对#define只实行字符替换,未有项目安检,並且在字符替换或然会发出意料不到的失实。

这种意况还大概出现以下错误
Sending ‘const NSString *__strong’ to parameter of type ‘NSString *’
discards qualifiers
由来是亟需NSString* 的地点使用了const NSString*

// 定义多少个指针变量int*p =NULL;// 定义2个int类型的变量inta =10;intb
=30;// p指向ap = &a;*p =20;// p指向bp = &b;*p =40;NSLog(@”%d %d”, a,
b);

2. cell标识
// JPHomeCellID,仅限当前文件,不可改,只占一份内存空间。static NSString *const JPHomeCellID = @"JPHomeCellID";

诸如:作者在A.m文件中扬言并定义了二个全局变量BOOL isSelected =
NO;
如下图:

解决办法正是

.h中 extern const NSString* 替换为extern NSString* const
.m中const NSString* 替换为 NSString* const
分解:前面贰个也就是指针本人不可修改,前者表示指针指向的剧情不可修改,两个的效用都是使字符串只可读不可写。

const修饰的*p

3. UCRUISERL字符串,保证满世界内部存款和储蓄器独有一份且全世界都能够访问,且不可改造

亚州城ca88手机版 8

被const修饰的*p只可以被赋值三遍,今后不能够赋值,不然编写翻译器报错

3.1 思路深入分析
  • 整个世界都能够访谈:全数无法用static
  • 环球内部存款和储蓄器都独有一块:无法用#define宏(多次正片,会设有多块内存)定义;
  • 不行改换:定义为常量

 

// const修饰的*pconstint*p =NULL;intconst*p = null;*p =20;//
编写翻译器报错,不可能改改*p的值

3.2 技术方案
  • 方案一:定义常量归入pch文件 : 短处-> 全部的类引用,重复定义

// 不可行,因为pch文件内容会拷贝到每一个文件中,这样会引起重复定义问题NSString *const JPRequestURL = @"http://baidu.com";
  • 方案二:麻烦

    • 1.常量的概念放在二个const.m文件中

NSString *const JPRequestURL = @””;

 - 2.然后在pch文件中引用const.m文件中定义的常量```objc extern NSString *const JPRequestURL; // extern 引用常量,这样就解决的只在pch中定义常量引起的重复定义的问题,而且保证了一份内存
  • 3.劣势:如果有玖15个,就须求在const.m文件中定义玖18个常量,然后在pch文件中利用extern援用九十六个概念的常量

  • 方案三:

    • 简短,化解了方案二中援引麻烦的难题
    • 步骤:

      • 在const.m中定义常量的值,

NSString *const JPRequestURL = @””;

 + 在const.h文件(引用定义的全局常量)中引用定义的全局常量 ```objc#import <UIKit/UIKit.h>// URLUIKIT_EXTERN NSString *const JPRequestURL;

+ 在pch文件中导入const.h文件即可

#import "const.h"

自家只要在B.m文件中宣示同名的变量BOOL isSelected =
NO;
会报错,截图如下:

const修饰的p

4. 定义Rect结构体变量commonRect,供给唯有本文件中能访谈,且不得修改
  • 接纳全局管理,替代宏定义

  • 思路深入分析:唯有本文件中能访谈 ->
    static修改commonRect变量;不可修改 -> 且还用const修改;

  • 留神:Rect结构体创造有两张情势 : CGRectMake(0,0,50,50)
    ->运维时手艺明显其值;{{0,0},{50,50}}
    ->编写翻译时就规定其值了。怎样挑选吗?

    • 很举世瞩目,大家要求定义常量,还记得常量的潜法规是如何吧?->
      常量的值必需编写翻译时就鲜明,不然会报错的,所以大家不得不通过{{0,0},{50,50}}形式开创布局体常量。
  • 实现

// 正确static CGRect const commonRect = {{0,0},{50,50}}; // 错误static CGRect const commonRect = CGRectMake(0,0,50,50);

亚州城ca88手机版 9

被const修饰的p只可以存一到处点,未来再也不能够其余存地址了,不然编写翻译器报错

1. 只限本文件中做客
  • 在.m中写上边代码

static 类型 const 常量名 = 常量值;

不留余地那些主题素材的方法有二种:

// const修饰的指针变量pint*constp =NULL;inta =20;p = &a;//
编写翻译器报错,不可能改改指针变量p

2. 满世界都要拜会
  • 1>在const.m文件中,(const.m定义全部全局常量)

#import <UIKit/UIKit.h>类型 const 常量名 = 常量值;.........
  • 2>在const.m文件中,写下列代码

#import <UIKit/UIKit.h>UIKIT_EXTERN 类型 const 常量名;.........
  • 3>在pch文件中包罗const.m文件,导入头文件

#import "const.h"

率先种:A.m文件中的全局变量注解为static的,代表只幸好当前文件访谈(当前文件可知):static
BOOL isSelected = NO;

const在阐明字符串的用法

第三种:B.m文件中用extern援用A.m文件中表达定义的那个全局变量:引用情势:extern
BOOL isSelected;
如下图:

NSString*constZMJName =@”jack”;

亚州城ca88手机版 10

static和const联合使用

 

static将贰个全局变量产生局地变量

利用第三种艺术:代表B.m文件和A.m文件使用的是同多少个BOOL类型的变量!!!借使A.m文件把isSelected
改为YES,那么B.m文件使用那么些isSelected时索要当心了,此时isSelected也是YES!!!

const将八个局地变量产生局地常量

注意:

// 定义了八个有个别常量staticconstCGFloatZMJRed
=0.4;staticconstCGFloatZMJ格林 =0.6;staticconstCGFloatZMJBlue =0.7;

  1. 上边extern BOOL isSelected;那句代码不是宣称变量,而是引用变量。

使用static const 与 #define

2.
形似景观下,假使别的文件中不会访谈本文件中的全局变量,那么建议用static关键字张开修饰,比方:static
BOOL isSelected = NO;

利用static const修饰变量和宏定义的比较

 

相同点

都无法再被修改

一处修改,另外都改了

不同点

static const修饰变量唯有一份内部存款和储蓄器

宏定义,只是简短的轮换,每趟使用都需求创建一份内部存款和储蓄器

结论

选取static const修饰尤其飞速,在同叁个文件内能够使用static
const取代#define

// static const修饰变量独有一份内部存款和储蓄器staticconstCGFloat ZMJRed =0.4;//
宏定义,只是用0.4替换ZMJRed,每回使用都亟需成立一份内部存款和储蓄器#defineZMJRed0.4

const实际付出的应用

一般会先新建ZMJConst.h文件极度寄放常量的引用

//
援用某变量,若无选用const修饰,就不可能直接在编写翻译的时候就可以检验是或不是修改了ZMJRedexternconstCGFloatZMJRed;externNSString*constZMJName;

能够效仿系统UIKIT_EXTERubiconN来替代extern,逼格越来越高!

UIKIT_EXTERNconstCGFloatZMJRed;UIKIT_EXTERNNSString*constZMJName;

相似会新建ZMJConst.m文件特别寄存static
const修饰的变量,须求用的时候导入头文件就能够了。

// 定义了上上下下程序都能访问的常量constCGFloatZMJRed
=0.4;NSString*constZMJName =@”jack”;

文/zhazha(简书笔者)

原稿链接:

小说权归作者全数,转发请联系小编得到授权,并标注“简书小编”。

一、const与宏的区分(面试题):

const简要介绍:此前常用的字符串常量,一般是分红宏,但是苹果不推荐我们分红宏,推荐大家选取const常量。

编写翻译时刻:宏是预编写翻译(编写翻译以前处理),const是编译阶段。

编写翻译检查:宏不做检讨,不会报编写翻译错误,只是交替,const会编写翻译检查,会报编写翻译错误。

宏的好处:宏能定义一些函数,方法。 const不能够。

宏的坏处:使用多量宏,轻易导致编译时间久,每趟都须求再度交换。

注意:非常多Blog都说使用宏,会损耗过多内部存款和储蓄器,笔者那表达并不会转换比较多内部存款和储蓄器,宏定义的是常量,常量都坐落常量区,只会生成一份内部存储器。

亚州城ca88手机版 11

Snip20151014_1.png

// 常见的常量:分红宏#define XMGAccount @”account”#define
XMGUserDefault [NSUserDefaults standardUserDefaults]//
字符串常量staticNSString*constaccount =@”account”;- (void)viewDidLoad
{    [superviewDidLoad];// 偏幸设置存款和储蓄// 使用宏[XMGUserDefault
setValue:@”123″forKey:XMGAccount];//
使用const常量[[NSUserDefaultsstandardUserDefaults]
setValue:@”123″forKey:account];}

二、const成效:限制类型

1.const仅仅用来修饰右侧的变量(基本数据变量p,指针变量*p)

2.被const修饰的变量是只读的。

const基本使用

– (void)viewDidLoad {    [super viewDidLoad];// 定义变量inta =1;//
同意修改值a =20;// const二种用法// const:修饰基本变量p//
那二种写法是同等的,const只修饰左侧的着力变量bconstintb =20;//
b:只读变量intconstb =20;// b:只读变量// 差别意修改值b =1;//
const:修饰指针变量*p,带*的变量,正是指针变量.//
定义多少个对准int类型的指针变量,指向a的地址int*p = &a;intc =10;    p =
&c;// 允许修改p指向的地点,// 允许修改p访谈内部存款和储蓄器空间的值*p =20;//
const修饰指针变量访问的内存空间,修饰的是左边手*p1,//
三种方法一样constint*p1;// *p1:常量 p1:变量intconst*p1;// *p1:常量
p1:变量// const修饰指针变量p1int*constp1;// *p1:变量 p1:常量//
第一个const修饰*p1 第三个const修饰 p1//
二种办法一样constint*constp1;// *p1:常量 p1:常量intconst*constp1;//
*p1:常量 p1:常量}

三、const开拓中运用境况:

1.急需1:提供三个形式,那一个格局的参数是地方,里面只可以通过地方读取值,无法经过地点修改值

2.要求2:提供三个格局,这一个措施的参数是地点,里面不可能修改参数的地方。

@implementationViewController// const放*前边约束参数,表示*a只读//
只好修改地址a,不可能通过a修改访谈的内部存款和储蓄器空间- (void)test:(constint* )a{// 
  *a = 20;}// const放*末尾约束参数,表示a只读//
不能够修改a的地址,只好修改a访谈的值- (void)test1:(int*const)a{intb;//
会报错a = &b;    *a =2;}- (void)viewDidLoad {   
[superviewDidLoad];// Do any additional setup after loading the view,
typically from a nib.inta =10;//
需要1:提供三个艺术,那一个艺术的参数是地点,里面只可以通过地点读取值,不能够通过地点修改值。//
那时候就必要利用const,约束措施的参数只读.[selftest:&a];//
须求2:提供二个格局,那些艺术的参数是地方,里面无法改改参数的地址。[selftest1:&a];}@end

四、static和extern简单利用(要动用贰个东西,先通晓其职能)

static作用:

修饰局地变量:

1.延伸部分变量的生命周期,程序甘休才会销毁。

2.局地变量只会生成一份内部存款和储蓄器,只会起初化三次。

3.转移部分变量的效能域。

修饰全局变量

1.只好在本文件中访问,修改全局变量的效能域,生命周期不会改

2.防止重复定义全局变量

extern作用:

只是用来得到全局变量(饱含全局静态变量)的值,不能用于定义变量

extern职业规律:

先在此时此刻文件查找有未有全局变量,未有找到,才会去别的文件查找。

// 全局变量:只有一份内部存款和储蓄器,全体文件共享,与extern联合利用。inta =20;//
static修饰全局变量staticintage =20;- (void)test{//
static修饰局地变量staticintage =0;    age++;NSLog(@”%d”,age);}-
(void)viewDidLoad {    [superviewDidLoad];// Do any additional setup
after loading the view, typically from a nib.[selftest];   
[selftest];externintage;NSLog(@”%d”,age);}I

五、static与const联合利用

static与const成效:声美素佳儿(Friso)个只读的静态变量

支付应用情况:在二个文件中平日利用的字符串常量,能够利用static与const组合

// 开采中常用static修饰全局变量,只更动功用域//
为何要更动全局变量作用域,幸免重复申明全局变量。//
开采中声称的全局变量,有个别不期望外面更动,只同意读取。//
比如叁个主旨数据类型不指望外人改变//
声雅培个静态的大局只读常量staticconstinta =20;//
staic和const联合的功用:声爱他美(Aptamil)个静态的全局只读常量//
iOS中staic和const常用利用处境,是用来替代宏,把二个平时利用的字符串常量,定义成静态全局只读变量.//
开辟中时时得到key修改值,由此用const修饰key,表示key只读,不一样意修改。staticNSString*constkey
=@”name”;// 如果 const修饰
*key1,表示*key1只读,key1还是能够改换。staticNSStringconst*key1
=@”name”;

六、extern与const联合利用

开采中使用处境:在七个文本中平时应用的一致个字符串常量,能够使用extern与const组合。

原因:

static与const组合:在各类文件都亟需定义一份静态全局变量。

extern与const组合:只需要定义一份全局变量,八个文件分享。

全局常量正规写法:开拓中便于管理全数的全局变量,常常搞四个GlobeConst文件,里面特意定义全局变量,统一保管,要不然项目文件多倒霉找。

GlobeConst.h

/*******************************首页****************************/extern
NSString * const nameKey =
@”name”;/*******************************首页****************************/

GlobeConst.m

#import
/*******************************首页****************************/NSString
* const nameKey =
@”name”;/*******************************首页****************************/

Post Author: admin

发表评论

电子邮件地址不会被公开。 必填项已用*标注