当前位置 : 主页 > 编程语言 > c语言 >

static修饰的变量及其作用域和生命周期

来源:互联网 收集:自由互联 发布时间:2023-09-07
目录 一.变量的作用域和生命周期 1.局部变量 (1)定义在函数的局部变量 (2)定义在代码块的局部变量 2.全局变量 (1)本源文件的全局变量 (2)跨文件的全局变量 二.static修饰的变


 目录

一.变量的作用域和生命周期

1.局部变量

(1)定义在函数的局部变量

(2)定义在代码块的局部变量

2.全局变量

(1)本源文件的全局变量

(2)跨文件的全局变量

 二.static修饰的变量性质及其作用域和生命周期

1.static修饰局部变量的性质

(1)未用static修饰

(2)用static修饰

2.static修饰全局变量

三.总结

1.static修饰局部变量总结

2.static修饰全局变量总结



一.变量的作用域和生命周期

1.局部变量

        定义在函数内或者在代码块内的变量为局部变量,它的作用域为本函数内或者本代码块内局部变量在出函数或者出代码块后就会被释放其生命周期为函数开始到函数结束

(1)定义在函数的局部变量

      我们将一个变量a定义在一个函数中,在主函数中调用该函数后再访问变量a,如下图所示

static修饰的变量及其作用域和生命周期_变量的作用域和生命周期

static修饰的变量及其作用域和生命周期_变量的作用域和生命周期_02

       可以看到编译器报错并显示变量a未定义,我们以指针的形式再作一次证明,在函数内定义一个变量a,并在函数结束时返回变量的地址,在主函数调用该函数并定义指针接受函数的返回值——变量a的地址

static修饰的变量及其作用域和生命周期_变量的作用域和生命周期_03

输出结果

static修饰的变量及其作用域和生命周期_变量的作用域和生命周期_04

       可以看到,确实打印出了变量a的值,这是为什么呢,明明局部变量a在函数结束后就被释放了,那我们在上面的基础再多打印一次试下

static修饰的变量及其作用域和生命周期_变量的作用域和生命周期_05

输出结果

static修饰的变量及其作用域和生命周期_变量的作用域和生命周期_06

       可以看到第二次通过解引用打印变量a出现了随机值,这是因为函数被调用完之后变量a随即被释放,而之所以第一次能够打印出来是因为编译器对被释放的变量a做了临时保存 

       通过上述两次测试,我们可以知道,定义在函数中的局部变量在函数结束后会被释放,即其作用域为函数体内,生命周期为函数开始到函数结束

(2)定义在代码块的局部变量

        首先说一下代码块的概念,{   }花括号里面的范围即为代码块,函数、循环、if判断等都有自己的花括号{}即代码块

       我们在代码块内定义变量a,在代码块后面再次访问变量a,如下图所示

static修饰的变量及其作用域和生命周期_变量的作用域和生命周期_07

static修饰的变量及其作用域和生命周期_变量的作用域和生命周期_08

        可以看到编译器报错并显示变量a未定义,经过验证,定义在代码块的变量在代码块结束后随机被被释放,即其作用域为本代码块内,生命周期为代码块开始到代码块结束

2.全局变量

        定义在函数外的变量称之为全局变量,其作用域为本源文件全局或者整个 工程 

(1)本源文件的全局变量

       首先补充一下文件的一些知识点,为了降低项目维护的成本以及程序的简洁高效,在很多项目中都会采用多文件的方式进行编程,一般会将函数和变量的实现放在源文件中,即.c为后缀的文件称之为源文件,将函数和变量的声明放在头文件中,即.h为后缀的文件称之为头文件,在源文件中使用include引入源文件。即可访问和调用其他相应源文件的一些函数和变量

      我们在主函数所在的源文件定义一个全局变量a,在自定义函数和主函数分别访问,如下图所示

static修饰的变量及其作用域和生命周期_变量的作用域和生命周期_09

 输出结果 

static修饰的变量及其作用域和生命周期_变量的作用域和生命周期_10

可以看到我们在fun函数和主函数都访问了变量a,并都访问成功,下面我们试着在一个函数内对变量a进行修改,然后在其他函数内打印

static修饰的变量及其作用域和生命周期_变量的作用域和生命周期_11

 输出结果

static修饰的变量及其作用域和生命周期_变量的作用域和生命周期_12

        可以看到我们在fun函数内将变量a修改成20,然后在主函数调用fun函数后再打印变量a的值,打印的值为20,即fun函数内修改的值 

        经过上述验证,我们可以知道全局变量在本源文件任何函数都可以对其进行访问和读写,即全局变量的作用域为本源文件全局,生命周期为从程序开始到程序结束

(2)跨文件的全局变量

              一个项目往往含有多个源文件,我们可以进行跨文件访问全局变量,前提是需要将其他源文件的全局变量相应的头文件声明并且包含头文件即可访问

test.c内容

static修饰的变量及其作用域和生命周期_变量的作用域和生命周期_13

 test.h内容

static修饰的变量及其作用域和生命周期_变量的作用域和生命周期_14

 在主函数中我们访问test.c中的函数和全局变量

static修饰的变量及其作用域和生命周期_变量的作用域和生命周期_15

 输出结果

static修饰的变量及其作用域和生命周期_变量的作用域和生命周期_16

        可以看到我们顺利地在主函数跨文件访问了全局变量a,我们尝试着在主函数内对其值进行修改并打印

static修饰的变量及其作用域和生命周期_变量的作用域和生命周期_17

输出结果

static修饰的变量及其作用域和生命周期_变量的作用域和生命周期_18

        可以看到我们成功的在主函数修改了跨文件的全局变量a的值

        经过上述验证,我们可以知道全局变量是可以进行跨文件访问和读写的,其作用域为整个项目全局,生命周期为从程序开始到程序结束

 二.static修饰的变量性质及其作用域和生命周期

1.static修饰局部变量的性质

         用static修饰局部变量可以使局部变量的生命周期变为全局,但其作用域不变

         我们定义一个函数验证,该函数功能为让变量a自增1

(1)未用static修饰


static修饰的变量及其作用域和生命周期_变量的作用域和生命周期_19

 输出结果

static修饰的变量及其作用域和生命周期_变量的作用域和生命周期_20

       可以看到调用10次函数打印出来的值都为1,原因是每次调用fun函数都会临时开辟一块空间用来放变量a,函数结束后空间随机被释放,再次调用fun函数,又会重新开辟一块空间用来放变量a,以此循环,故每次定义变量a=0,自增1则变为1,

(2)用static修饰

        在上面的基础上,我们对fun函数的局部变量进行static修饰

static修饰的变量及其作用域和生命周期_变量的作用域和生命周期_21

输出结果

static修饰的变量及其作用域和生命周期_变量的作用域和生命周期_22

        输出结果为每次调用fun函数变量a便自增1,调用10次即自增了10次,可以从中知道,在每次调用函数时,变量a的值为上次调用函数完之后的值,且a的值只初始化了一次,让我们看起来static修饰的变量a好像具有“记忆”功能

       当我们在主函数内对static修饰的变量a进行访问时

static修饰的变量及其作用域和生命周期_变量的作用域和生命周期_23

static修饰的变量及其作用域和生命周期_变量的作用域和生命周期_24

        可以看到编译报错并显示变量a未定义

        经过上述验证,我们可以知道用static修饰的全局变量生命周期变为全局,但其作用域不变

2.static修饰全局变量

        static修饰全局变量主要影响全局变量的跨文件访问即其作用域,用static修饰的全局变量只在本源文件有效,即其作用域为本源文件,生命周期为从程序开始到程序结束

        我们在test.c源文件中定义一个全局变量,在主函数进行访问,看其被static修饰前后的效果

test.c内容

static修饰的变量及其作用域和生命周期_变量的作用域和生命周期_25

 main.c内容

static修饰的变量及其作用域和生命周期_变量的作用域和生命周期_26

输出结果

static修饰的变量及其作用域和生命周期_变量的作用域和生命周期_27

 可以看到我们成功地在主函数跨文件访问了test.c中的全局变量,下面我们对该变量进行static修饰

test.c

static修饰的变量及其作用域和生命周期_变量的作用域和生命周期_28

 输出结果

static修饰的变量及其作用域和生命周期_变量的作用域和生命周期_29

       可以看到,在我们用static修饰test.c文件中的全局变量a并在主函数中调用,编译器报错并显示变量a为无法解析的变量,此次跨文件访问失败

        上述访问失败的原因为,用static修饰的全局变量a会变为只在本源文件中有效,我们在test.c的函数Test函数访问变量a

test.c

static修饰的变量及其作用域和生命周期_变量的作用域和生命周期_30

main.c

static修饰的变量及其作用域和生命周期_变量的作用域和生命周期_31

输出结果

static修饰的变量及其作用域和生命周期_变量的作用域和生命周期_32

        可以看到我们通过test.c中的函数可以访问变量a

        综合上述验证,我们可以基本总结出用static修饰的全局变量的性质,即其作用域变为只在源文件有效,生命周期为从程序开始到程序结束,虽然不能跨文件直接访问static修饰的全局变量,但是可以通过其所在源文件的函数间接访问,该性质主要应用于一些实际项目的隐私性,可以间接访问,但不可以对其进行修改,可以有效地保护数据的安全

三.总结

1.static修饰局部变量总结

        static修饰的局部变量具有“记忆”功能,其只会被初始化一次,其生命周期较普通局部变量变长了,从局部变为全局,即从程序开始到程序结束,但其作用域和普通局部变量一样,依然只能作用域函数内或者所在代码块内

2.static修饰全局变量总结

        static修饰的局部变量主要影响全局变量的跨文件访问,即主要影响其作用域,其作用域从整个工程变为本源文件,只在本源文件内才可以被访问,其他源文件需要跨文件调用它只能通过它所在源文件的函数间接访问,这也是保护数据的一种方式,但其生命周期不变,依然为从程序开始到程序结束

 



上一篇:【数据结构】静态链表
下一篇:没有了
网友评论