c语言函数静态存储?C语言动态变量和静态变量的区别
一、c语言变量的储存类别及各自的特点
auto变量是用堆栈(stack)方式占用储存器空间,因此,当执行此区段是,系统会立即为这个变量分配存储器空间,而程序执行完后,这个堆栈立即被系统收回.在大括号{}内声明.
自动变量就是指在函数内部定义使用的变量。他只是允许在定义他的函数内部使用它。在函数外的其他任何地方都不能使用的变量。自动变量是局部变量,即它的区域性是在定义他的函数内部有效。当然这说明自动变量也没有链接性,因为它也不允许其他的文件访问他。由于自动变量在定义他的函数的外面的任何地方都是不可见的,所以允许我们在这个函数外的其他地方或者是其他的函数内部定义同名的变量,他们之间不会发生冲突的。因为他们都有自己的区域性,而且它没有链接性(即:不允许其他的文件访问他的)。来看看自动量的持续性。计算机在执行这个函数的时候,创建并为它分配内存,当函数执行完毕返回后,自动变量就会被销毁。这个过程是通过一个堆栈的机制来实现的。为自动变量分配内存就压栈,而函数返回时就退栈。
局部变量按照存储形式可分为三种auto, static, register。
与auto类型(普通)局部变量相比, static局部变量有三点不同:
auto类型分配在栈上,属于动态存储类别,占动态存储区空间,函数调用结束后自动释放,而static分配在静态存储区,在程序整个运行期间都不释放.两者之间的作用域相同,但生存期不同.
2. static局部变量在所处模块在初次运行时进行初始化工作,且只*作一次。
3.对于局部静态变量,如果不赋初值,编译期会自动赋初值0或空字符,而auto类型的初值是不确定的.
特点: static局部变量的”记忆性”与生存期的”全局性”
所谓”记忆性”是指在两次函数调用时,在第二次调用进入时,能保持第一次调用退出时的值.
1.“记忆性”,程序运行很重要的一点就是可重复性,而static变量的”记忆性”破坏了这种可重复性,造成不同时刻至运行的结果可能不同.
2.“生存期”全局性和唯一性.普通的local变量的存储空间分配在stack上,因此每次调用函数时,分配的空间都可能不一样,而static具有全局唯一性的特点,每次调用时,都指向同一块内存,这就造成一个很重要的问题----不可重入性!!!
在C中static有了第二种含义:用来表示不能被其它文件访问的全局变量和函数。,但为了限制全局变量/函数的作用域,函数或变量前加static使得函数成为静态函数。但此处“static”的含义不是指存储方式,而是指对函数的作用域仅局限于本文件(所以又称内部函数)。注意此时,对于外部(全局)变量,不论是否有static限制,它的存储区域都是在静态存储区,生存期都是全局的.此时的static只是起作用域限制作用,限定作用域在本模块(文件)内部.
使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名。
外部变量定义在程序外部,所有的函数很程序段都可以使用.
外部变量可能会在某一程序段被重新定义,以段内变量为参考值.
静态外部变量和外部变量差别在于,外部变量生命可以同时给多个文件使用,而静态外部变量则只能给声明此变量的文件使用.
寄存器变量,是由寄存器分配空间,访问速度比访问内存快,加快执行速度.寄存器大小有限.
在c语言当中可以使用寄存器变量来优化程序的性能,常见的是在一个函数体当中,将一个常用的变量声明为寄存器变量: register int ra;如果可能的话,编译器就会为它分配一个单独的寄存器,在整个函数执行期间对这个变量的*作全都是对这个寄存器进行*作,这时候就不用频繁地去访存了,自然就提高了性能。
不能用于全局变量。现在的情况是VC忽略用户定义的REGISTER,因此定义一个REGISTER变量与不定义一个REGISTER是一样的,编译器进行相同的优化,因为MS认为,REGISTER是系统中宝贵的资源,应该由系统统一调配,而且认为VC编译器的优化能力要大于一般的程序员。因此也有人说register关键字在PC机(x86CPU)无用,编译器按自动变量处理。
register int j; int*p=&j;是错的,因为无法对寄存器的定址。
二、C语言动态变量和静态变量的区别
1、静态变量是在定义的时候,有static修饰的变量,形式为static TYPE var_name= init_value;
2、动态变量,形式为TYPE var_name= init_value;即没有static修饰,其中的=init_value均可省略。
3、动态全局变量:作用域为整个项目,即终编译成可执行文件的所有文件中均可以使用动态全局变量,生命周期为从程序运行到程序退出,即贯穿整个运行时间。
4、静态全局变量:作用域为当前文件,从定义/声明位置到文件结尾,生命周期为从程序运行到程序退出,即贯穿整个运行时间。
5、静态变量也可以用于存储常数。具体来说,静态变量(全局变量及汇编语言里定义的符号亦同)可用const,constant或final(根据语言决定)等关键字标识,这时其值就会在编译时设定,并且无法在运行时改变。
6、编译器通常将静态常量与文本一起置于目标文件的文本区域,而非常量初始化数据则置于数据区;而如若有需要,有些编译器还可选择为其开辟专用区;为防止常数变量被错误的指针写入覆盖,亦可在这块区域启用内存保护机制。
7、以上内容参考:百度百科-静态变量
三、c语言静态存储数组的赋值问题。
1、使用static定义静态数组,这个数组就会在程序的整个生命周期里存在,并且这个数组会分配并放在程序的.bss段中,这个段中的所有数据都是会被自动初始化为0的,如果是声明在函数中,那么调用这个函数每次使用的数组都是同一个数组,如果不是在函数中定义,那么这个数组就仅限于在此文件中可用。
2、而没有static声明的数组,这个数组会在调用这个函数所在的栈帧中分配,也就是在栈上分配,这个数组就不会被初始化,数组中的值是随机的,如果在函数中定义,那么调用这个函数时每次使用的数组一般是不同的。
3、至于要不要用static来声明,一方面是看你是否需要这个数组被长久使用,另一方面就是看是否需要让它自动初始化为0,还有就是在其他文件中是否需要使用这个数组。
四、C语言初始化数组时,一定要使用静态存储吗
1、ANSI/ISO C之前,对数组的一次性初始化必须要求数组被声明为静态的,楼上说static和extern与变量的使用范围有关,没错,但不是这里要使用的含义,这里静态(全局变量默认为静态的)指的是该变量只初始化一次。全局变量肯定是只初始化一次的,所以这主要是针对函数块里面声明的变量来说的,就是说在函数块里面声明的静态局部变量,只在第一次进入这个函数块的时候才进行初始化。ANSI/ISO C允许对声明的非静态数组也进行一次性初始化。所以在支持ANSI/ISO C标准的编译环境下,函数块内写
2、函数块外面写static时才是楼上所说的变量的适用范围,不加static声明出来的变量的范围可以在文件之间,加了static声明的变量则只在该文件内。但此时,你加不加static都不会影响你写int a[3]={ 2, 4, 5};因为这个时候a是全局变量,默认的是静态的,这样的初始化当然没有问题的。
3、另外,这种一次性初始化必须在定义一个变量的时候才是允许的。这一点,楼主要谨记,不管是ANSI/ISO C还是C99都是不允许出现
4、的,不管有没有static修饰。如果你不想在定义的时候初始化,那就只有等到你需要的时候通过赋值*作来进行,数组当然得通过循环。