static变量的作用域_static变量的作用域

static变量的作用域_static变量的作用域在C语言中,变量的生存期是由变量的存储类型说明的,变量的存储类型决定了变量的生存期,即决定变量何时“生”,何时“灭”

变量的作用域和生存期
1、变量的作用域
程序中被花括号括起来的区域,叫做语句块(Block)。函数体是语句块,分支语句和循环体也是语句块。
变量的作用域(Scope)规则是:每个变量仅在定义它的语句块(包含下级语句块)内有效,并且拥有自己的存储空间。
不在任何语句块内定义的变量,称为全局变量(Global Variable)全局变量的作用域为整个程序,即全局变量在程序的所有位置均有效。这是因为假如把整个程序看作一个大语句块,按照变量的作用域规则,在与main()平行的位置即不在任何语句块内定义的变量,就应该在程序的所有位置均有效。
相反,在除整个程序以外的其他语句块内定义的变量,称为局部变量(Local Variable)
全局变量从程序运行开始起就占据内存,仅在程序结束时才将其释放,所谓释放内存,其实就是将内存中的值恢复为随机值(即乱码)。由于全局变量的作用域是整个程序,在程序运行期间始终占据着内存,因此在程序运行期间的任何时候,在程序的任何地方,都可以访问(读或者写)全局变量的值。

例题:用递归方法编程输出Fibonacci数列的基础上,同时打印出计算Fibonacci数列每一项时所需的递归调用次数。

#include <stdio.h> int count; long fib(int n); int main() { 
    int n,i,x; printf("Input n:"); scanf("%d",&n); for(i=1;i<=n;i++) { 
    count = 0; x = fib(i); printf("fib(%d)=%d,count = %d\n",i,x,count); } return 0; } long fib(int n) { 
    count++; if(n==0) return 0; else if(n==1) return 1; else return(fib(n-1)+fib(n-2)); } 

在这里插入图片描述
程序定义了全局变量count,用于累计递归函数调用次数,这里虽未对count初始化,但全局变量不指定初值时会自动初始化为0,因此此时count的值仍为0。
使用太多的全局变量,和使用太多的goto语句标号一样,都会导致程序混乱不堪,很难保证哪个变量不会被意外修改,也很难推断变量的值究竟是在哪个地方被修改的,而任何一个函数对它的修改都会作用到全局,同样,依赖全局变量的函数也会受此影响。

变量占用着不同的内存单元,有着不同的作用域,因此不会互相干扰。

2、变量的生存周期:
变量的生存周期是指变量从生成到被撤销的时间段,即从分配内存到释放内存的时间段,实际上就是变量占用内存的时间。在C语言中,变量的生存期是由变量的存储类型说明的,变量的存储类型决定了变量的生存期,即决定变量何时“生”,何时“灭”。变量的存储类型的一般声明方式如下:
存储类型 数据类型 变量名表;

变量只能在其生存期间内被访问,而变量的作用域也会影响变量的生存期。因此,C语言中提供的存储类型主要有以下几种:
(1)自动变量 (Automatic Variable)
(2)静态变量 (Static variable)
(3)外部变量 (Extern Variable)
(4)存储器变量 (Register Variable)

2.1自动变量(Automatic Variable)
自动变量的标准定义格式:
auto 类型名 变量名:
例如:
auto int temp;
由于自动变量极为常用,所以C语言把它设计成缺省的存储类型,即auto可以省略不写。反之,如果没有指定变量的存储类型,那么变量的存储类型就是缺省为auto。
自动变量的“自动”体现在进入语句块时自动申请内存,退出语句块时自动释放内存。它仅能被语句块内的语句访问,再退出语句块以后不能在访问。因此,自动变量也称为动态局部变量。
2.2静态变量(Static Variable)
静态变量的定义格式为:
static 类型名 变量名;
一个自动变量(即动态局部变量)再退出定义后它的函数后,因系统给他分配的内存已经被释放,下次再进入该函数时,系统会给它重新分配内存,因此它的值是不会被保留的。如果希望系统为其保留这个值,除非系统分配给它的内存在退出函数调用时不释放。这时就要用到静态变量。

例题:计算n!。

#include <stdio.h> long func(int n); int main() { 
    int i,n; while(1) { 
    printf("Input n:"); scanf("%d",&n); for(i=1;i<=n;i++) { 
    printf("%d!=%ld\n",i,func(i)); } } return 0; } long func(int n) { 
    static long p=1; p=p*n; return p; } 

在这里插入图片描述
由此可以看出static会“记住“定义变量的值,使其不会被释放;发生了改变会记住改变的值。

2.3外部变量
格式:
extern 类型名 变量名;
如果在所有函数之外定义的变量没有指定其存储类别,那么他就是一个外部变量。外部变量是全局变量,它的作用域是从它的定义到本文件的末尾。但是如果要在定义 点之前或者在其他文件中使用它,那么就需要定义为外部变量。
和静态变量一样,外部变量也是在静态存储区内分配内存的,其生存周期是整个程序的运行期。没有显示初始化的外部变量由编译程序自动初始化为0。
区别在于他们的作用域有可能是不同的,这取决于静态变量是在哪里被访问,而在所有函数外定义的静态变量,称为全局静态变量,但是只能在本文件中调用,其他文件,无法调用。

2.4寄存器变量
寄存器变量就是用寄存器存储的变量。
其格式定义为:
register 类型名 变量名
寄存器(Register)是CPU内部的一种容量有限但速度极快的存储器。由于cpu进行访问时内存的操作很耗时,是的有时对内存的访问无法于指令的执行保持同步。因此,将需要频繁访问的数据存放在CPU内部的存储器里,即使使用频率较高的变量声明为register,可以避免cpu对存储器的频繁数据访问,是程序更小,执行速度更快。

今天的文章
static变量的作用域_static变量的作用域分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/81172.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注