C/C++变量的四种存储类型(auto自动、static静态、extern外部、register寄存器)

喵~对于一个变量来说,有三个维度需要了解:作用域、链接和存储期

  • 一、前言:
    • 1.1 作用域:
      • 1.1.1 块作用域:
      • 1.1.2 函数作用域:
      • 1.1.3 函数原型作用域:
      • 1.1.4 文件作用域:
    • 1.2 链接:
    • 1.3 存储期:
      • 1.3.1 静态存储期
      • 1.3.2 线程存储期
      • 1.3.3 自动存储期
      • 1.3.4 动态分配存储期
    • 总结:各种存储期、作用域和链接方式之间的关系
  • 二、 存储变量类型分类
  • 2.1 自动变量(auto):
  • 2.2 寄存器变量(register):
  • 2.3 静态变量(static):在变量前加上static 关键字的变量
    • 2.3.1 局部静态变量
    • 2.3.2 全局静态变量
  • 2.4 外部变量(extern)
  • 2.5 变量的作用域和生存周期

一、前言:

1.1 作用域:

也就是变量可见的范围
一个变量的作用域可以是:块作用域、函数作用域、函数原型作用域、文件作用域。下面对四种作用域进行简要介绍

1.1.1 块作用域:

for(int i = 0;i < num;i++){},其中i具有块作用域,一旦离开for循环就不能再访问i。

1.1.2 函数作用域:

void show(){int i = 0;……},其中i具有函数作用域,只能函数 show() 内部进行访问

1.1.3 函数原型作用域:

int sum(int num1,int num2);num1 num2具有函数原型作用域,可见范围为形参定义到原型声明完毕

1.1.4 文件作用域:

#include <iostream>
#include <stdlib.h>
using namespace std;
int num = 900;
int main(){}

其中num具有文件作用域,从定义开始到文件结尾均可进行访问

1.2 链接:

链接分为外部链接、内部链接以及无连接块作用域、函数以及函数原型作用域都属于无链接,因为它们在文件中都受限于一个小块中访问,想与外部或者文件中其他地方建立链接根本不可能,所以属于无链接。相反文件作用域不同,其可以是外部链接也可以是内部链接,外部链接的就是多文件程序使用,内部链接的话只能用于某个单元中。

#include <stdio.h>
#include <stdlib.h>
int num = 500;
static int num1 = 200;

代码中int num = 500;属于文件作用域,外部链接static int num1 = 200;属于文件作用域,内部链接

1.3 存储期:

也就是变量存活的时段
分为四种:静态存储期、线程存储期、自动存储期以及动态分配存储期

1.3.1 静态存储期

如果对象拥有静态存储期,那么它就会在程序运行期间一直存在。对于具有文件作用域的变量,不管其是具有内部链接还是外部链接的,都具有静态存储期。当然了具有块作用域的变量也能够具有静态存储期,下面代码中变量ct虽然是具有块作用域,但它是保存在静态内存中,从程序调用到结束期间一直存在

void show(int number){static int ct = 900;
}

1.3.2 线程存储期

如果对象拥有线程存储期,那么它就会从声明到线程结束一直存在

1.3.3 自动存储期

我们目前使用的大部分变量都是具有自动存储器的变量,尤其一些具有块作用域的变量都具有自动存储期,如下代码所示,变量 number和index在调用函数show时被创建,离开函数时被销毁,那么他就具有块作用域,并且是自动存储期,从块的开始处到结尾。

void show(int number){int index = 900;
}

1.3.4 动态分配存储期

请戳一下这边:C/C++内存管理(内存分布、动态内存分配、动态内存分配与释放、内存泄漏等)

总结:各种存储期、作用域和链接方式之间的关系

请添加图片描述

二、 存储变量类型分类

所有的数据都有两种类型
数据类型: 如int,float
存储类型: 总共有四种存储类型的变量,分别为自动变量(auto)、静态变量
static)、外部变量(extern)以及寄存器变量(register)。

2.1 自动变量(auto):

auto - 函数中所有的非静态局部变量,程序中默认的变量都是auto自动变量。例如:int num = 100;num就是一个自动变量,auto是可以省略的,但只限于C语言中,C++中不能加auto.

C语言中,int num = 100 和 auto int num = 100;是相同的,C++中auto int num = 100 会报错。

2.2 寄存器变量(register):

寄存器是CPU上面的一个挂件,运行速度很快,一般用在某些常被访问的变量上,将该变量设置为寄存器变量存储在寄存器中方便CPU使用。即某个变量如果一直要被CPU使用的话,存储在寄存器中要比存储在内存中读取起来快的多。

注意点1:
例如:register int num = 100;
num被声明成一个寄存器变量,其保存在寄存器中是打印不出地址的&num,但是如果使用printf(“ox%p”,&num);打印其地址的,就会变成普通的auto变量。

注意点2:
寄存器变量不能定义到全局变量位置

总结:知其所在就好,尽量不要使用,因为编译器会自动去优化

2.3 静态变量(static):在变量前加上static 关键字的变量

2.3.1 局部静态变量

静态变量在整个程序生命周期中只拷贝一份,如果某函数内的静态变量被访问并且值发生了改变,那么他就会保存新的值。

void static_demo(){static int girl = 18;++girl;
}

该函数被调用一次之后girl变为19,下次再调用,进入函数之后girl就变成19了,并不是函数内定义的18。如果是自动变量就会不一样了。请看下面demo。

2.3.2 全局静态变量

定义在最前面的static int num = 100;
在代码中任何地方都可以访问到,而局部静态变量只能在定义他的函数或者块中才能访问到

2.4 外部变量(extern)

把全局变量在其他源文件中声明成extern 变量,可以扩展该全局变量的作用域至声明的那个文件,其本质作用就是对全局变量作用域的扩展
假设有文件aa.c:

#include <stdio.h>
int num = 520;

文件bbb.c:

#include <stdio.h>
#include <stdlib.h>
extern int num;
int main(void){printf("num = %d",num);return 0;
}

输出>>:num = 520;将变量num声明成外部变量extern,可以将num的作用域拓展至bbb.c文件中。

2.5 变量的作用域和生存周期

在这里插入图片描述

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

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

相关文章

Maynor的博客专家成长之路——暨2023年中复盘

文章目录 博客专家成长之路——暨2023年中复盘前言念念不忘的博客专家每天只做三件事敲代码写博客健健身 我的感悟 不足之处未来&#xff1a;和CSDN共同成长最后 博客专家成长之路——暨2023年中复盘 前言 ​ 2023年不知不觉已经过去了半年有余&#xff0c;也是时候作年中复盘…

TOWARDS A UNIFIED VIEW OF PARAMETER-EFFICIENT TRANSFER LEARNING

本文也是属于LLM系列的文章&#xff0c;针对《TOWARDS A UNIFIED VIEW OF PARAMETER-EFFICIENT TRANSFER LEARNING》的翻译。 关于参数有效迁移学习的统一观点 摘要1 引言2 前言2.1 Transformer结构综述2.2 之前的参数高效调优方法综述 3 弥合差距-统一的视角3.1 仔细观察Pref…

容器技术概述

容器是一种轻量级的、操作系统级别的虚拟化技术&#xff0c;它允许我们在资源隔离的进程中运行应用程序及其依赖项。运行应用程序所需的所有必要组件都可以打包为单个可以复用的映像。当映像被执行时&#xff0c;它将运行在一个孤立的环境中&#xff0c;不会与宿主操作系统共享…

设计模式之结构型模式

本文已收录于专栏 《设计模式》 目录 概念说明大话设计模式结构型模式 各模式详解适配器模式&#xff08;Adapter Pattern&#xff09;桥接模式&#xff08;Bridge Pattern&#xff09;组合模式&#xff08;Composite Pattern&#xff09;装饰器模式&#xff08;Decorator Patt…

刘汝佳samaのDLX详解

引入 精确覆盖问题&#xff08;Exact Cover Problm&#xff09; 有一些由整数 1~n 组成的集合 S 1 , S 2 , S 3 , … , S r S_1,S_2,S_3,…,S_r S1​,S2​,S3​,…,Sr​&#xff0c; 要求选择若干个集合 S i S_i Si​,使1~n 的每个整数恰好在一个集合中出现。比如&#xff0c…

基于JSP+Servlet的文件上传与下载

基于JSPServlet的文件上传与下载 一、系统介绍二、功能展示1.项目骨架2.单文件上传3.多文件上传4.下载文件1.其他系统实现五.获取源码 一、系统介绍 项目类型&#xff1a;Java web项目 项目名称&#xff1a;基于JSPServlet的文件上传与下载案例 项目架构&#xff1a;B/S架构…

Flutter学习四:Flutter开发基础(五)资源管理

目录 0 引言 1 资源管理 1.1 指定 assets 1.2 Asset 变体&#xff08;variant&#xff09; 1.3 加载 assets 1.3.1 加载文本 1.3.2 加载图片 1.3.2.1 声明分辨率相关的图片 1.3.2.2 加载图片 1.3.3 依赖包中的资源图片 1.3.4 打包包中的 assets 1.3.5 特定平台 as…

【Spring】— Spring MVC复杂数据绑定

目录 复杂数据绑定1.绑定数组2.绑定集合 复杂数据绑定 实际项目开发中&#xff0c;除了简单数据类型外&#xff0c;还会经常遇到一些比较复杂的数据绑定问题&#xff0c;比如数组的绑定、集合的绑定&#xff0c;接下来将具体讲解一下数组绑定和集合绑定的使用。 1.绑定数组 …

adb 工具

小白初如嵌入式的坑&#xff0c;对于串口调试工具&#xff0c;之前一直只知道有SecureCRT这一种方式&#xff1b; 但是在最近一次的使用过程中&#xff0c;发现抢占资源的情况出现&#xff0c;两个进程之间相互打架&#xff0c;这个时候需要 查看top&#xff08;嵌入式板子资…

此导入从不用作值,必须使用 “import type“ ,因为 “importsNotUsedAsValues“ 设置为 “error“。

前言 最近电脑更新了一次系统&#xff0c;重启后在 VsCode中打开项目 &#xff0c;发现原本正常的代码出现了一堆语法提示。网上搜了一下&#xff0c;没有找到关于此问题的回答&#xff0c;不知道我是不是第一个遇到的。在此记录一下这次的经历&#xff0c;如果有其他人遇到&a…

数据结构--队列的基本概念

数据结构–队列的基本概念 队列的定义 队列其实是一种受限制的线性表 队列(Queue)&#xff1a;是 只允许在一端进行插入或删除操作 \color{red}只允许在一端进行插入或删除操作 只允许在一端进行插入或删除操作的线性表 重要术语: 队头、队尾、空队列 队列的特点: 先进先出 \…

5.4.1 虚拟专用网VPN

5.4.1 虚拟专用网VPN 我们已经学习了因特网的路由协议&#xff08;5.3.1 因特网的路由协议&#xff08;一&#xff09;、5.3.2 因特网的路由协议&#xff08;二&#xff09;基于距离向量算法的RIP协议、5.3.3 因特网的路由协议&#xff08;三&#xff09;OSPF协议、5.3.4 因特…