【iOS】static、extern、const、auto关键字以及联合使用

news2024/9/21 19:08:41

目录

    • 前言
      • extern关键字
      • static关键字
      • const关键字
    • 联合使用
      • static和extern
      • static和const
      • extern和const
    • auto关键字


先了解一下静态变量所在的全局/静态区的特点:【iOS】内存五大分区

前言

上面提到的全局/静态区中存放的是全局变量或静态变量:

全局变量是指变量值可以在运行时被动态修改
静态变量static修饰的变量,包含静态局部变量和静态全局变量

extern关键字

extern只能用来修饰全局变量,不能修饰其他变量,一般定义的全局变量默认带有extern,只不过被省略了,多用于跨文件引用

1. 与.h文件的关系

.h文件时为了更好地方便其他文件去调用本文件中的变量、属性和方法,作用同extern

如果在.h文件中声明全局变量,在OC中是不合法的,主要在@interface ExternModel : NSObject@end之间,当然如果在他们两个之外也是可以声明的:

在这里插入图片描述

应显式声明extern表明其不是成员变量,而是全局变量:

@interface ExternModel : NSObject
extern NSString* xyString;
@end

常见用法:

.h结合extern使用:如果在.h文件中声明了extern全局变量,那么在同一个类中的.m文件对全局变量的赋值必须时:数据类型+变量名(与声明时一致) = XXXXX,并且在调用时导入.h文件:

//  ExternModel.h
#import <Foundation/Foundation.h>
@interface ExternModel : NSObject
extern NSString* xyString;
@end

//  ExternModel.m
#import "ExternModel.h"
@implementation ExternModel
NSString* xyString = @"Hello!!";
@end

例如,在viewController.mmain.m中调用,则可以引入ExternModel.h,否则无法识别全局变量

在这里插入图片描述

当然也可以通过不导入头文件的方式进行调用,通过extern调用,来获取全局变量的值

2. extern引用变量

如果在其他文件中访问一个类的全局变量,可以不用导入.h文件,通过extern去直接访问:

#import <Foundation/Foundation.h>
//#import "ExternModel.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
    //  只是用来获取全局变量(包括全局静态变量)的值,不能用于定义变量
        extern NSString* xyString;
        NSLog(@"%@", xyString);
    }
    return 0;
}
//  Hello!!

static关键字

static修饰变量后该变量就被定义成为一个静态变量

静态全局变量

static修饰全局变量,存储区仍在全局/静态区,但限定了该全局变量只能在当前源文件访问(从定义之处开始到文件结尾),限制了其作用域,在外部文件中是不可见的

好处: 定义后只会指向固定的指针地址,供当前文件使用,同一源程序的其他文件中可以使用相同名字的变量,不会发生冲突
不足: 存在的生命周期长,从定义直到程序结束
建议: 从内存优化和程序编译的角度来说,尽量少用全局静态变量,因为存在的生命周期长,一直占用空间。程序运行时会单独加载一次全局静态变量,过多的全局静态变量会造成程序启动慢

静态局部变量

static修饰局部变量,存储区由栈区变为静态区(.rwdata),延长了该局部变量的生命周期,虽然直到源程序结束该变量才会被销毁,但其作用域仍为局部,即当定义该变量的函数或者语句块结束时,就不可使用,尽管该变量仍存在

好处: 定义后只会存在一份值,只会初始化一次,每次调用都是使用的同一个对象内存地址的值,并没有重新创建,节省空间
不足: 存在的生命周期长,从定义直到程序结束
建议: 静态全局和局部变量从根本上没有什么区别,只是作用域不同而已。如果仅一个类中的对象和类方法使用并且值可变,可以定义全局静态变量

静态函数

在函数的返回类型前加上关键字static,函数就被定义成为静态函数

函数的实现和声明默认情况下是extern的,当函数被static修饰成为静态函数后,该函数的作用域仅限于定义它的源文件,同一程序的其他文件无法直接调用该函数,也无法通过外部链接访问

好处: 同一源程序的其他文件中可以使用相同名字的变函数,不会发生冲突;编译器可对static静态函数进行更多的优化,因为已知该函数不会在其他源文件中使用

const关键字

const是用来修饰常量(只读值)的,注意与宏的区别(EOC 2.0里面有提到《Effective Objective-C 2.0》读书笔记——熟悉Objective-C,良好的编码习惯提倡我们多用类型常量,少用#define类型常量):

在这里插入图片描述

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

const仅仅用来修饰右边的变量:

// 定义变量
int a = 1;
// 允许修改值
a = 20;
// const两种用法
// 1.const:修饰基本变量p
// 这两种写法是一样的,const只修饰右边的基本变量b
const int b = 20; // b:只读变量
int const b = 20; // b:只读变量
// 不允许修改值
b = 1;
// 2. const:修饰指针变量*p,带*的变量,就是指针变量
// 定义一个指向int类型的指针变量,指向a的地址
int *p = &a;
int c = 10;
// 允许修改p指向的地址
p = &c;
// 允许修改p访问内存空间的值
*p = 20;
// const修饰指针变量访问的内存空间,修饰的是右边*p1,
// 两种方式一样
const int *p1; // *p1:常量 p1:变量
int const *p1; // *p1:常量 p1:变量
// 允许修改p指向的地址
p1 = &a;
// 不允许修改p访问内存空间的值
*p1 = 27;
// const修饰指针变量p1
int * const p2; // *p1:变量 p1:常量
// 不允许修改p指向的地址
p2 = &a;
// 允许修改p访问内存空间的值
*p2 = 27;
// 第一个const修饰*p1 第二个const修饰 p1
// 两种方式一样
const int * const p3; // *p1:常量 p1:常量
int const * const p3; // *p1:常量 p1:常量
// p的指向和指向内存空间的值都不能修改
p3 = &a;
*p3 = 27;

在这里插入图片描述

联合使用

static和extern

extern引用变量时会先在当前文件查找有没有全局变量,没有找到,才会去其他文件查找

static int age = 21;

void test(void) {
    static int age = 21;
    age++;
    NSLog(@"%d", age);
}

int main(void) {
    test();
    test();
    
    extern int age;
    NSLog(@"%d", age);
    return 0;
}
// 打印结果:
// 22
// 23
// 21

static和const

声明一个只读的静态变量,常用于声明上面《EOC 2.0》提到的类型常量

// 开发中经常将无需改变的key值作为类型(字符串)常量
static NSString* const key1 = @"keyValue1";
static NSString const * key2 = @"keyValue2";
static const NSString* key3 = @"keyValue3";

extern和const

声明一个全局的类型常量,供多个文件共享

全局常量正规写法:开发中便于管理所有的全局变量,通常搞一个GlobeConst文件,里面专门定义全局变量,统一管理,要不然项目文件多不好找

// GlobeConst.h
extern NSString * const kGlobalConstKey;

// GlobeConst.m
NSString * const kGlobalConst = @"globalConst";

auto关键字

认识了这么多修饰变量的关键字,最后再来简单认识一下之前未了解过的auto关键字

变量被auto修饰后,编译器会根据初始化表达式自动推断出变量的类型:

auto x = 3.14;      // x 是浮点型 double
auto y = 520;       // y 是整形 int
auto z = 'a';       // z 是字符型 char
auto nb;            // error,变量必须要初始化
auto double nbl;    // 语法错误, 不能修改数据类型   
auto pi = new auto(42); // pi 的类型被推导为 int*
const auto& y = x; // y 的类型被推导为 const int&

auto关键字更适用于类型冗长复杂、变量使用范围专一时,使程序更清晰易读。如:

 std::vector<int> vect; 
 for (auto it = vect.begin(); it != vect.end(); ++it)
 {  //it的类型是std::vector<int>::iterator
    std::cin >> *it;
  }

或者保存lambda表达式类型的变量声明:

  auto ptr = [](double x){return x*x;};//类型为std::function<double(double)>函数对象

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1936761.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

逻辑回归(Logistic Regression,LR)

分类和回归是机器学习的两个主要问题。 分类处理的是离散数据回归处理的是连续数据 线性回归&#xff1a;回归 拟合一条线预测函数&#xff1a; 逻辑回归&#xff1a;分类——找到一条线可以将不同类别区分开 虽然称为逻辑回归&#xff0c;但是实际是一种分…

Chromium CI/CD 之Jenkins实用指南2024-在Windows节点上创建任务(九)

1. 引言 在现代软件开发流程中&#xff0c;持续集成&#xff08;CI&#xff09;和持续交付&#xff08;CD&#xff09;已成为确保代码质量和加速发布周期的关键实践。Jenkins作为一款广泛应用的开源自动化服务器&#xff0c;通过其强大的插件生态系统和灵活的配置选项&#xf…

【第4章】Spring Cloud之Nacos单机模式支持mysql

文章目录 前言一、初始化1. 初始化数据库2. 修改配置文件 二、效果1. 重新启动2. 新增用户 总结 前言 在0.7版本之前&#xff0c;在单机模式时nacos使用嵌入式数据库实现数据的存储&#xff0c;不方便观察数据存储的基本情况。0.7版本增加了支持mysql数据源能力&#xff0c;具…

数据如光,科技助航丨泰迪智能科技2024年暑期数据分析学徒班正式开班

7月16日&#xff0c;泰迪智能科技2024年暑期数据分析学徒班在泰迪智能科技天河培训中心正式开班&#xff0c;泰迪智能科技培训业务部孙学镂、教学代表周津、授课讲师巫兴港、就业指导老师赵欣欣、孟宪同、教学班主任黄晨华出席此次开班仪式。 仪式伊始&#xff0c;孙学镂代表广…

达梦数据库的系统视图v$arch_status

达梦数据库的系统视图v$arch_status 在达梦数据库&#xff08;DM Database&#xff09;中&#xff0c;V$ARCH_STATUS 是一个动态性能视图&#xff08;Dynamic Performance View&#xff09;&#xff0c;用于显示归档日志的状态信息。这个视图可以帮助数据库管理员监控和管理数…

【Linux服务器Java环境搭建】010在linux中安装Redis,以及对Redis的配置与远程连接

系列文章目录 【Linux服务器Java环境搭建】 前言 好久没有更新博客了&#xff0c;今天下了班回到家&#xff0c;看到电脑桌上尘封已久的《Spring Boot应用开发实战》&#xff0c;翻开目录想起来之前写的系列【Linux服务器Java环境搭建】还未完结&#xff0c;那就继续吧&#…

通义千问AI模型对接飞书机器人-模型配置(2-1)

一 背景 根据业务或者使用场景搭建自定义的智能ai模型机器人&#xff0c;可以较少我们人工回答的沟通成本&#xff0c;而且可以更加便捷的了解业务需求给出大家设定的业务范围的回答&#xff0c;目前基于阿里云的通义千问模型研究。 二 模型研究 参考阿里云帮助文档&#xf…

IDEA的断点调试(Debug)

《IDEA破解、配置、使用技巧与实战教程》系列文章目录 第一章 IDEA破解与HelloWorld的实战编写 第二章 IDEA的详细设置 第三章 IDEA的工程与模块管理 第四章 IDEA的常见代码模板的使用 第五章 IDEA中常用的快捷键 第六章 IDEA的断点调试&#xff08;Debug&#xff09; 第七章 …

基于chrome插件的企业应用

一、chrome插件技术介绍 1、chrome插件组件介绍 名称 职责 访问权限 DOM访问情况 popup 弹窗页面。即打开形式是通过点击在浏览器右上方的icon&#xff0c;一个弹窗的形式。 注: 展示维度 browser_action:所有页面 page_action:指定页面 可访问绝大部分api 不可以 bac…

数据分析入门:用Python和Numpy探索音乐流行趋势

一、引言 音乐是文化的重要组成部分&#xff0c;而音乐流行趋势则反映了社会文化的变迁和人们审美的变化。通过分析音乐榜单&#xff0c;我们可以了解哪些歌曲或歌手正在受到大众的欢迎&#xff0c;甚至预测未来的流行趋势。Python作为一种强大的编程语言&#xff0c;结合其丰…

【数据库系列】Parquet 文件介绍

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

记录些Spring+题集(8)

Spring Bean 的生命周期 Spring Bean 的生命周期涉及到 Spring 框架中对象的创建、初始化、使用和销毁等关键过程。 在Spring框架中&#xff0c;Bean的生命周期经历以下几个阶段&#xff1a; 1&#xff09;实例化&#xff1a; Spring 根据配置文件或注解等方式创建 Bean 实例…

《0基础》学习Python——第十八讲__爬虫\<1>

一、什么是爬虫 爬虫是一种网络数据抓取的技术。通过编写程序&#xff08;通常使用Python&#xff09;&#xff0c;爬虫可以自动化地访问网页&#xff0c;解析网页内容并提取出所需的数据。爬虫可以用于各种用途&#xff0c;如搜索引擎的索引&#xff0c;数据分析和挖掘&#x…

vue 腾讯云 javascript sdk + 简单富文本组件设计+实战

<template><div><quill-editor v-model"content" ref"myQuillEditor" :options"editorOption" change"onEditorChange"input"handleInput"></quill-editor><!-- 链接添加对话框 --><el-di…

随手记:推荐vscode好用的几个小插件

原始用了挺久的插件&#xff0c;先上截图&#xff0c;以后有空再编辑&#xff1a; fittenCode 是一个AI小助手&#xff0c;相对来说很智能&#xff0c;你在vscode当中编写代码&#xff0c;甚至都可以知道你下一步知道干嘛&#xff0c;训练的还可以。而且还可以帮你起名字&…

spring MVC 简单的案例(2)用户登录

一、用户登录 1&#xff09;前端代码 index.html <!doctype html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport"content"widthdevice-width, user-scalableno, initial-scale1.0, maxim…

Filebeat k8s 部署(Deployment)采集 PVC 日志发送至 Kafka——日志处理(二)

文章目录 前言Filebeat Configmap 配置Filebeat Deployment验证总结 前言 在上篇文章中总结了 Django 日志控制台输出、文件写入按天拆分文件&#xff0c;自定义 Filter 增加 trace_id 以及过滤——日志处理&#xff08;一)&#xff0c;将日志以 JSON 格式写入日志文件。我们的…

【BUG】已解决:SyntaxError invalid syntax

SyntaxError invalid syntax 目录 SyntaxError invalid syntax 【常见模块错误】 错误原因&#xff1a; 解决办法&#xff1a; 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰&#xff0c;211科班出身&#xff0c;就职于…

CentOS 7 安装Jenkins2.346.1(war方式安装)

既然想要安装Jenkins&#xff0c;肯定是先要从官网解读所需环境配置信息&#xff0c;如需了解更多自行查阅 https://www.jenkins.io/doc/book/installing/linux/ JDK17&#xff0c;Maven3.9 安装 先从官网分别下载JDK17与Maven3.9 下载好之后上传至服务器、并解压&#xff1a…

【体外诊断】ARM/X86+FPGA嵌入式计算机在医疗CT机中的应用

体外诊断 信迈科技提供基于Intel平台、AMD平台、NXP平台的核心板、2.5寸主板、Mini-ITX主板、4寸主板、PICO-ITX主板&#xff0c;以及嵌入式准系统等计算机硬件。产品支持GAHDMI等独立双显&#xff0c;提供丰富串口、USB、GPIO、PCIe扩展接口等I/O接口&#xff0c;扩展性强&…