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 
#include 
using namespace std;
int num = 900;
int main(){}

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

1.2 链接:

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

#include 
#include 
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++内存管理(内存分布、动态内存分配、动态内存分配与释放、内存泄漏等)

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

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

二、 存储变量类型分类

所有的数据都有两种类型
数据类型: 如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 
int num = 520;

文件bbb.c:

#include 
#include 
extern int num;
int main(void){
	printf("num = %d",num);
	return 0;
}

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

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

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

你可能感兴趣的:(c语言,c++,算法)