C++中的存储类及其实例

文章目录

    • 0. 语法
    • 1. 自动存储类
      • 自动存储类对象的属性
      • 自动存储类的例子
    • 2. 外部存储类
      • extern存储类对象的属性
      • extern存储类的例子
    • 3. 静态存储类
      • 静态存储类的属性
      • 静态存储类的例子
    • 4. 寄存器存储类
      • 寄存器存储类对象的属性
      • 寄存器存储类例子
    • 5. 可变(mutable)存储类
      • 可变存储类的属性
      • 可变存储类的例子
    • 6. thread_local存储类
      • thread_local存储类属性
      • thread_local存储类的例子

C++存储类用于描述变量/函数的特性。它确定了生命周期、可见性、默认值和存储位置,这有助于我们在程序运行时跟踪特定变量。存储类说明符用于指定变量的存储类。

0. 语法

要指定变量的存储类,请遵循以下语法:

storage_class var_data_type var_name;

C++使用了6个存储类,如下所示:

  1. auto Storage Class
  2. register Storage Class
  3. extern Storage Class
  4. static Storage Class
  5. mutable Storage Class
  6. thread_local Storage Class

在这里插入图片描述
以下是对每个存储类的详细说明:

1. 自动存储类

自动存储类是块内声明的所有变量的默认类。auto 代表自动,块中声明的所有局部变量都自动属于此类。

自动存储类对象的属性

  • 范围:本地/局部
  • 默认值:垃圾值
  • 内存位置:RAM
  • 生命期:直到其范围结束

自动存储类的例子

// C++ Program to illustrate the auto storage class
// variables
#include <iostream>
using namespace std;void autoStorageClass()
{cout << "Demonstrating auto class\n";// Declaring an auto variableint a = 32;float b = 3.2;char* c = "GeeksforGeeks";char d = 'G';// printing the auto variablescout << a << " \n";cout << b << " \n";cout << c << " \n";cout << d << " \n";
}int main()
{// To demonstrate auto Storage ClassautoStorageClass();return 0;
}

输出

Demonstrating auto class
32 
3.2 
GeeksforGeeks 
G 

注意:在C++早期,我们可以使用auto关键字显式声明自动变量,但在C++11之后,auto关键字的含义发生了变化,我们不能再使用它来定义自动变量。

2. 外部存储类

extern存储类只是简单地告诉我们变量是在其他地方定义的,而不是在使用它的同一块中(即外部链接)。基本上,该值在不同的块中被赋值,也可以在不同的块中重写/更改。外部变量只不过是一个全局变量,该全局变量在声明时使用合法值初始化,以便在其他地方使用。

在任何函数/块中的声明/定义之前放置 “extern” 关键字,可以将普通全局变量设置为 extern。使用外部变量的主要目的是,可以在大型程序的两个不同文件之间访问它们。

extern存储类对象的属性

  • 范围:全局
  • 默认值:0
    • 内存位置:RAM
  • 生命期:直到程序结束

extern存储类的例子

// C++ Program to illustrate the extern storage class
#include <iostream>
using namespace std;// declaring the variable which is to
// be made extern an initial value can
// also be initialized to x
int x;
void externStorageClass()
{cout << "Demonstrating extern class\n";// telling the compiler that the variable// x is an extern variable and has been// defined elsewhere (above the main// function)extern int x;// printing the extern variables 'x'cout << "Value of the variable 'x'"<< "declared, as extern: " << x << "\n";// value of extern variable x modifiedx = 2;// printing the modified values of// extern variables 'x'cout << "Modified value of the variable 'x'"<< " declared as extern: \n"<< x;
}int main()
{// To demonstrate extern Storage ClassexternStorageClass();return 0;
}

输出

Demonstrating extern class
Value of the variable 'x'declared, as extern: 0
Modified value of the variable 'x' declared as extern: 
2

有关外部变量如何工作的更多信息,请查看此链接。

3. 静态存储类

静态存储类用于声明在C++语言中编写程序时常用的静态变量。静态变量具有即使在超出其作用域后也能保留其值的特性!因此,静态变量保存了它们在作用域中最后一次使用的值。

我们可以说,它们只初始化一次,并且一直存在到程序终止。因此,没有分配新的内存,因为它们没有被重新声明。全局静态变量可以在程序中的任何位置访问。

静态存储类的属性

  • 范围:本地/局部
  • 默认值:0
    • 内存位置:RAM
  • 生命期:直到程序结束

注意:全局静态变量可以在任何函数中访问。

静态存储类的例子

// C++ program to illustrate the static storage class
// objects
#include <iostream>
using namespace std;// Function containing static variables
// memory is retained during execution
int staticFun()
{cout << "For static variables: ";static int count = 0;count++;return count;
}// Function containing non-static variables
// memory is destroyed
int nonStaticFun()
{cout << "For Non-Static variables: ";int count = 0;count++;return count;
}int main()
{// Calling the static partscout << staticFun() << "\n";cout << staticFun() << "\n";// Calling the non-static partscout << nonStaticFun() << "\n";cout << nonStaticFun() << "\n";return 0;
}

输出

For static variables: 1
For static variables: 2
For Non-Static variables: 1
For Non-Static variables: 1

4. 寄存器存储类

寄存器存储类使用“register”关键字声明寄存器变量,该关键字具有与自动变量相同的功能。唯一的区别是,如果有可用的寄存器,编译器会尝试将这些变量存储在微处理器的寄存器中。这使得程序运行时,寄存器变量的使用比存储在内存中的变量的使用快得多。如果没有可用寄存器,则这些寄存器变量仅存储在内存中。

这里需要注意的一个重要而有趣的点是,我们不能使用指针来获得寄存器变量的地址。

寄存器存储类对象的属性

  • 范围:本地/局部
  • 默认值:垃圾值
    • 内存位置:CPU中的寄存器或RAM
  • 生命期:直到其范围结束

寄存器存储类例子

// C++ Program to illustrate the use of register variables
#include <iostream>
using namespace std;void registerStorageClass()
{cout << "Demonstrating register class\n";// declaring a register variableregister char b = 'G';// printing the register variable 'b'cout << "Value of the variable 'b'"<< " declared as register: " << b;
}
int main()
{// To demonstrate register Storage ClassregisterStorageClass();return 0;
}

输出

Demonstrating register class
Value of the variable 'b' declared as register: G

注意register关键字在C++17以后的版本中已被弃用。

5. 可变(mutable)存储类

有时需要通过const函数修改类/结构体的一个或多个数据成员,即使您不希望该函数更新类/结构体中的其他成员。使用mutable关键字可以很容易地执行此任务。关键字mutable主要用于允许修改const对象的特定数据成员。

当我们将函数声明为const时,传递给函数的指针就变成了const。给变量添加mutable可以让const指针改变成员。

可变存储类的属性

可变说明符不影响对象的链接或生存期。它将与在该位置声明的正常对象相同。

可变存储类的例子

// C++ program to illustrate the use of mutalbe storage
// class specifiers
#include <iostream>
using std::cout;class Test {
public:int x;// defining mutable variable y// now this can be modifiedmutable int y;Test(){x = 4;y = 10;}
};int main()
{// t1 is set to constantconst Test t1;// trying to change the valuet1.y = 20;cout << t1.y;// Uncommenting below lines// will throw error// t1.x = 8;// cout << t1.x;return 0;
}

输出

20

6. thread_local存储类

thread_local存储类是在C++11中添加的新存储类。我们可以使用thread_local存储类说明符将对象定义为thread_local。thread_local变量可以与其他存储说明符(如static或extern)组合,thread_local对象的属性也会相应更改。

thread_local存储类属性

  • 内存位置:RAM
  • 生命期:直到它的线程结束

thread_local存储类的例子

// C++ program to illustrate the use of thread_local storage
// sprecifier
#include <iostream>
#include <thread>
using namespace std;// defining thread local variable
thread_local int var = 10;// driver code
int main()
{// thread 1thread th1([]() {cout << "Thread 1 var Value: " << (var += 18) << '\n';});// thread 2thread th2([]() {cout << "Thread 2 var Value: " << (var += 7) << '\n';});// thread 3thread th3([]() {cout << "Thread 3 var Value: " << (var += 13) << '\n';});th1.join();th2.join();th3.join();return 0;
}

输出

Thread 1 var Value: 28
Thread 2 var Value: 17
Thread 3 var Value: 23

可以看到,每个线程都有自己的thread_local变量副本,并且只被分配了在其可调用文件中指定的值。

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

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

相关文章

【机器学习】Boosting算法-梯度提升算法(Gradient Boosting)

一、原理 梯度提升算法是一种集成学习方法&#xff0c;它可以将多个弱分类器或回归器组合成一个强分类器或回归器&#xff0c;提高预测性能。梯度提升算法的核心思想是利用损失函数的负梯度作为残差的近似值&#xff0c;然后用一个基学习器拟合这个残差&#xff0c;再将其加到之…

二维码智慧门牌管理系统:提升社区管理智能化水平

文章目录 前言一、全方位信息录入与查询二、公安权限账户访问的公安大数据后台三、社区工作人员申请权限安装录入软件四、业主通过移动终端扫描标准地址二维码门牌自主申报录入五、系统的价值 前言 在数字化时代&#xff0c;社区管理面临着更新流动人口信息、准确录入六实相关…

docker安装入门及redis,minio,rabbitmq应用安装

部分笔记来自黑马课堂&#xff1a;【黑马程序员Docker快速入门到项目部署&#xff0c;MySQL部署Nginx部署docker自定义镜像DockerCompose项目实战一套搞定-哔哩哔哩】 https://b23.tv/niWEhEF 一、什么是docker&#xff1a; 快速构建、运行、管理应用的工具。--帮助我们快速部…

【中小型企业网络实战案例 二】配置网络互连互通

​【中小型企业网络实战案例 一】规划、需求和基本配置-CSDN博客 热门IT技术视频教程&#xff1a;https://xmws-it.blog.csdn.net/article/details/134398330?spm1001.2014.3001.5502 配置接入层交换机 1.以接入交换机ACC1为例&#xff0c;创建ACC1的业务VLAN 10和20。 <…

nginx反向代理服务器及负载均衡服务配置

一、正向代理与反向代理 正向代理&#xff1a;是一个位于客户端和原始服务器(oricin server)之间的服务器&#xff0c;为了从原始服务器取得内容&#xff0c;客户端向代理发送一个请求并指定目标(原始服务器)&#xff0c;然后代理向原始服务器转交请求并将获得的内容返回给客户…

南邮最优化期末复习

黄金分割法 单纯形法&#xff08;大M法&#xff09; 求min, σ找最小&#xff0c;终止条件全部大于0 θ找最小&#xff0c;且不能为负数求max, σ找最大&#xff0c;终止条件全部小于0 θ找最小&#xff0c;且不能为负数 例题 二阶段单纯形法想 分支定界法&#xff08;第二章&…

【单调队列】LeetCode1499:满足不等式的最大值

涉及知识点 单调队列 题目 给你一个数组 points 和一个整数 k 。数组中每个元素都表示二维平面上的点的坐标&#xff0c;并按照横坐标 x 的值从小到大排序。也就是说 points[i] [xi, yi] &#xff0c;并且在 1 < i < j < points.length 的前提下&#xff0c; xi &…

iMazing2024免费版iOS移动设备管理软件

以自己的方式管理iPhone&#xff0c;让备受信赖的软件为您传输和保存音乐、消息、文件和数据。安全备份任何 iPhone、iPad 或 iPod touch。iMazing 功能强大、易于使用&#xff0c;称得上是 Mac 和 PC 上最好的 iOS 设备管理器。 正在为iTunes繁琐的操作发愁&#xff1f;设备数…

leetcode——打家劫舍问题汇总

本章汇总一下leetcode中的打家劫舍问题&#xff0c;使用经典动态规划算法求解。 1、梦开始的地方——打家劫舍&#xff08;★&#xff09; 本题关键点就是不能在相邻房屋偷东西。 采用常规动态规划做法&#xff1a; 根据题意设定dp数组&#xff0c;dp[i]的含义为&#xff1a…

Typora Mac激活

首先去官网选择mac版本下载安装 typora下载 然后打开typora包内容找到 /Applications/Typora.app/Contents/Resources/TypeMark/page-dist 找到/static/js/Licen..如下图 编辑器打开上面文件夹 输入 hasActivated"true"e.hasActivated 进行搜索 将它改为 hasA…

人工智能:网络犯罪分子的驱动力

随着 2024 年的临近&#xff0c;是时候展望今年的网络安全状况了。由于网络犯罪日益复杂&#xff0c;预计到 2025 年&#xff0c;全球网络安全成本将增至 10.5 万亿美元。 人工智能的使用不断发展&#xff0c;网络犯罪分子变得越来越有创造力 我们注意到&#xff0c;联邦调查…

Dash中的callback的使用 多input 6

代码说明 import plotly.express as pxmport plotly.express as px用于导入plotly.express模块并给它起一个别名px。这样在后续的代码中&#xff0c;你可以使用px来代替plotly.express&#xff0c;使代码更加简洁。 plotly.express是Plotly的一个子模块&#xff0c;用于快速创…

路由器常见故障分析及处理方法!

对当前的大多数网络来说&#xff0c;无论是实现网络互连还是访问Internet&#xff0c;路由器是不可或缺的。 由于路由器的重要性&#xff0c;对它的管理就成了维护人员的日常工作中重要的一部分&#xff0c;而路由器的故障分析和排除也是令许多维护人员极为困扰的问题之一。 路…

jenkins Job华为云EIP变更带宽

引言: 在数字化时代&#xff0c;云服务资源的弹性管理是企业降低运营成本、提高效率的关键手段。通过弹性公网IP&#xff08;EIP&#xff09;服务&#xff0c;企业可以实现按需计费&#xff0c;优化网络支出。然而&#xff0c;根据业务流量的不同阶段调整计费模式&#xff0c;…

批量归一化

目录 一、BN层介绍 1、深层神经网络存在的问题 2、批量归一化的解决方案 3、BN层作用位置 4、BN层在做什么 5、总结 二、批量归一化从零实现 1、实现批量归一化操作 2、创建BN层 3、对LeNet加入批量归一化 4、开始训练 三、简明实现 1、对LeNet加入批量归一化 2…

【SD】IP-Adapter 进阶 - 垫图 【画风重绘-必看】

目录 关于SD1.5的画风迁移 修改动作-方法一&#xff1a;提示词 修改动作-方法二&#xff1a;openpose 关于SD1.5的画风迁移 1.5测试模型&#xff1a;flat2DAnimerge_v30_2.safetensors [b2c93e7a89] 测试图&#xff1a; 文生图&#xff1a;best quality,masterpiece, co…

20231225在WIN10下使用SSH连接Ubuntu20.04.6

20231225在WIN10下使用SSH连接Ubuntu20.04.6 2023/12/25 23:03 https://jingyan.baidu.com/article/5552ef479e1856108ffbc9e3.html Win10怎么开启SSH功能 Win10怎么开启SSH功能,下面就一起来看看吧! 工具/原料 华硕天选4 Windows10 方法/步骤 点击左下角的开始菜单,打开Wind…

Redis过期删除策略和内存淘汰策略

1、设置Redis键过期时间 Redis提供了四个命令来设置过期时间&#xff08;生存时间&#xff09;。 EXPIRE <key> <ttl> &#xff1a;表示将键 key 的生存时间设置为 ttl 秒。 PEXPIRE <key> <ttl> &#xff1a;表示将键 key 的生存时间设置为 ttl 毫秒。…

SICP : The Elements of Programming

好的计算机编程语言应具备的三个特性 基础单元表达式&#xff0c;计算机编程语言最最最基础单元&#xff0c;理应具备的表达式组合的能力&#xff0c;能够通过基础单元表达式组合成更复杂的元素抽象的能力&#xff0c;能通过复杂的元素抽象成更高层的单元 基础单元表达式 加 …

快速入门学习定时任务框架-xxljob

定时任务框架-xxljob 简介 主要用于分布式任务调度&#xff0c;可以将任务调度和执行分布在多个节点上。它提供了一个集中式的管理平台&#xff0c;支持动态添加、修改、删除任务&#xff0c;以及任务的分片执行&#xff0c;确保任务在分布式环境中的高可用性的一个框架 spr…