美文网首页iOS
基础:iOS中const的使用

基础:iOS中const的使用

作者: 喔牛慢慢爬 | 来源:发表于2021-03-23 15:36 被阅读0次

前言

我们在日常开发的时候经常需要定义一些公用的常量,比如消息通知的Key值、一些控件的宽高值等,我们经常使用#define宏或const来定义,有时候对于const的使用的很混乱,在这里记录下加深印象。之前一直使用宏定义字符串常量,但是苹果不推荐这样使用宏,推荐使用const定义常量字符串或其他类型常量。

宏与const的区别

  • 编译处理: 宏是预编译的,在编译之前在预处理器里进行文本替换的;const是在编译阶段使用的。
  • 类型检查: 宏没有类型,不做类型检查,仅仅是展开,替换文本;const具有类型,在编译时会检查常量类型。
  • 内存使用: 宏只是展开操作,不会分配内存,多少位置使用,就展开多次。占用的只是代码段,大量用宏会导致二进制文件变大;使用const修饰的全局静态常量共享一块内存,如果代码中多次使用,也不会多次分配内存;
  • 宏的优点: 使用宏可以定义一些函数方法付,单使用const修饰的常量无法定义函数方法;
  • 宏的缺点: 过多的使用宏定义会增加编译时间;

const的作用

  1. 在声明定义变量时用来修饰右侧的变量,基本变量或指针变量
  2. 如果变量被const修饰了,则此变量只能是只读的,无法修改变量值;

注:使用时主要关注const的位置,const只修饰表达式右边内容,被const修饰的内容都是常量,不能被修改,

const的基本使用

  • 正常定义变量:
//定义变量
int a = 1;
printf("值:%d 变量地址:%p 变量指向地址:%p\n",a,&a,a);
//值:1 变量地址:0x16dcab62c 变量指向地址:0x1
//对变量值进行修改
a = 20;
printf("值:%d 变量地址:%p 变量指向地址:%p\n",a,&a,a);
//值:20 变量地址:0x16dcab62c 变量指向地址:0x14
//未使用const修饰变量的时候,变量值可以修改
  • 第一种:修饰变量
const int b1 = 20;
b1 = 10;
//error:Cannot assign to variable 'b1' with const-qualified type 'const int'
//无法修改变量b1的值
int const b2 = 20;
b2 = 10;
//error:Cannot assign to variable 'b2' with const-qualified type 'const int'
//无法修改变量b2的值
//注:因此以上两种使用const的方式修饰右侧内容的效果是相同的!
  • 第二种:修饰指针变量
//定义指向int型的指针变量,指向a的地址
int *p = &a;
printf("p值:%d 指针变量地址:%p 指针变量指向地址:%p \n",*p,&p,p);
//p值:20 指针变量地址:0x16f40f618 指针变量指向地址:0x16f40f62c
//*p为取值,取得p的值;&p为指针p的地址;%p = p为指针p指向的地址
//p指向的地址与变量a的地址相同!

    
int c = 10;
printf("c值:%d c的地址:%p \n",c,&c);
//c值:10 c的地址:0x16b4a7614

    
//允许修改p指向的地址,指向变量c的地址
p = &c;
printf("p值:%d 指针变量地址:%p 指针变量指向地址:%p c值:%d\n",*p,&p,p,c);
//p值:10 指针变量地址:0x16b8f3618 指针变量指向地址:0x16b8f3614 c值:10

    
//允许修改p指向的内存中的值
*p = 20;
//此时变量c的值也会改变,打印c的值为20
printf("p值:%d 指针变量地址:%p 指针变量指向地址:%p c值:%d\n",*p,&p,p,c);
//p值:20 指针变量地址:0x16ce93618 指针变量指向地址:0x16ce93614 c值:20

*p是常量,p变量代码

//使用const修饰指针变量,修饰*p
int d = 30;
int e = 50;
int f = 55;

/*const在类型前面*/
const int *p1 = &d;
//此时:*p1是常量,不可修改;p1是变量,可修改;
printf("p1值:%d 指针变量地址:%p 指针变量指向地址:%p \n",*p1,&p1,p1);
//p1值:30 指针变量地址:0x16b0cb600 指针变量指向地址:0x16b0cb610
*p1 = 60;
// error: Read-only variable is not assignable
p1 = &f;
//p1为变量可以修改
printf("p1值Fix:%d 指针变量地址:%p 指针变量指向地址:%p \n",*p1,&p1,p1);
//p1值Fix:55 指针变量地址:0x16b0cb600 指针变量指向地址:0x16b0cb608
    

/*const在类型后面*/
int const *p2 = &d;
//此时:*p2是常量,不可修改;p2是变量,可修改;
printf("p2值:%d 指针变量地址:%p 指针变量指向地址:%p \n",*p2,&p2,p2);
//p2值:30 指针变量地址:0x16ddcb5f8 指针变量指向地址:0x16ddcb610
*p2 = 60;
// error: Read-only variable is not assignable
p2 = &e;
//p2为变量可以修改
printf("p2值Fix:%d 指针变量地址:%p 指针变量指向地址:%p \n",*p2,&p2,p2);
//p2值Fix:50 指针变量地址:0x16ddcb5f8 指针变量指向地址:0x16ddcb60c

//注:以上两种使用const的方式(在类型前或类型后)修饰右侧内容的效果是相同的!

*p是变量,p常量代码

 //const修饰指针变量p
int * const p3 = &d;
//此时:*p3为变量,可修改;p3为常量,不可修改;
printf("p3值:%d 指针变量地址:%p 指针变量指向地址:%p d值:%d\n",*p3,&p3,p3,d);
//p3值:30 指针变量地址:0x16d5fb5f0 指针变量指向地址:0x16d5fb610 d值:30
*p3 = e;
printf("p3值Fix:%d 指针变量地址%p 指针变量指向地址:%p d值:%d\n",*p3,&p3,p3,d);
//p3值Fix:50 指针变量地址0x16d5fb5f0 指针变量指向地址:0x16d5fb610 d值:50d值:50
p3 = &f;
//error: Cannot assign to variable 'p3' with const-qualified type 'int *const'

如何让*p和p都是常量不可修改呢?

这样

//如何让*p和p都是常量不可修改呢?
const int * const p4 = &d;//*p4为常量;p4为变量;
或
int const * const p5 = &d;//*p4为常量;p4为变量;

const与static使用

声明一个只读的静态变量,常用于声明定义常量字符串等。

  • static修饰全局变量,改变作用域;修饰局部变量,改变变量生命周期;
  • static改变作用域防止重复声明;
  • const将不希望被随意改变的变量,变为只读,不可修改;
// 声明一个静态的全局只读常量
static const int a = 20;
// 开发中经常拿到key修改值,因此用const修饰key,表示key只读,不允许修改。
static  NSString * const key = @"name";

const与extern使用

开发中经常遇到多个文件使用同一个字符串常量,我们可以使用const与extern组合声明定义字符串常量,一般将这类的字符串常量放入一个公用的全局文件中统一管理,只需要定义一份全局变量,多个文件共享。

#import <Foundation/Foundation.h>

extern NSString *const key;
@interface Unitilty : NSObject

@end

#import "Unitilty.h"

NSString *cone key = @"name";

@implementation Unitilty

@end

相关文章

网友评论

    本文标题:基础:iOS中const的使用

    本文链接:https://www.haomeiwen.com/subject/rkufhltx.html