首页 > 代码库 > C语言中static关键字的作用
C语言中static关键字的作用
C语言中static关键字的作用
华清远见2014-10-05 北京海淀区 张俊浩
一、C源程序编译后的可执行文件(elf)存储空间布局
1)正文段——CPU执行的机器指令部分;一个程序只有一个副本;只读,防止程序由于意外事故而修改自身指令;
2)初始化数据段(数据段)——在程序中所有赋了初值的全局变量,存放在这里。
3)非初始化数据段(bss段)——在程序中没有初始化的全局变量;内核将此段初始化为0。
4)栈——增长方向:自顶向下增长;自动变量以及每次函数调用时所需要保存的信息(返回
地址,局部变量,环境信息)。
5)堆——动态存储分。是向高地址扩展的数据类型,是自下向上的扩展方式。
存储说明符auto,register,extern,static,对应两种存储期模式:自动存储期和静态存储期。auto和register对应自动存储期。具有自动存储期的变量在进入声明该变量的程序块时被建立,它在该程序块活动时存在,退出该程序块时撤销。
关键字extern和static用来说明具有静态存储期的变量和函数。用static声明的局部变量具有静态存储持续期(static storage duration),或静态范围(static extent)。虽然他的值在函数调用之间保持有效,但是其名字的可视性仍限制在其局部域内。静态局部对象在程序执行到该对象的声明处时被首次初始化
二、生存周期
(1)局部变量在每次函数调用的时候分配空间,在函数调用结束之后销毁。
(2)全局变量在程序开始运行时分配空间,在程序结束时销毁。
(3)如果局部变量和全局变量重名,局部变量会暂时覆盖掉全局变量。
(4)全局变量只能用常量表达式初始化,因为程序开始运行时要用适当的值来初始化全局变量,所以初始值必须保存在编译生成的可执行文件中,因此初始值在编译时要计算出来。c语言从语法上规定,全局变量只能用常量表达式初始化。
三、C语言中static关键字的作用
【1】static作用的变量
1.static修饰全局变量:在全局变量前加static,全局变量就被定义成为一个全局静态变量。
特点如下:
1)存储区(内存中的位置):静态存储区没变(静态存储区在整个程序运行期间都存在);
2)初始化:未经初始化的全局静态变量会被程序自动初始化为0。(自动对象的值是任意的,除非他被显示初始化)
3)作用域:全局静态变量在声明他的文件之外是不可见的。准确地讲从定义之处开始到文件结尾。非静态全局 变量的作用域是整个源程序(多个源文件可以共同使用); 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。好处:
1)不会被其他文件所访问,修改;
2)其他文件中可以使用相同名字的变量,不会发生冲突。
2.static修饰局部变量:在局部变量之前加上关键字static,局部变量就被定义成为一个局部静态变量。特点如下:
1) 存储区(内存中的位置):由栈变为静态存储区rodata,生存期为整个源程序,只能在定义该变量的函数内使用。退出该函数后,尽管该变量还继续存在,但不能使用它;
2)初始化:为静态局部变量赋初值是在编译时进行的,即只赋初值一次,在程序运行时它已有初值。以后每次调用函数时不再重新赋初值而只是保留上次函数调用结束时的值。而为自动变量赋初值,不是在编译时进行的,而是在函数调用时进行,每调用函数重新给一次值,相对于执行一次赋值语句。如果在定义局部变量是不赋初值的话,对静态局部变量来说,编译时自动赋初值0(对数值型变量)或空字符(对字符型变量)。而对自动变量来说,如果不赋初值,则它的值是不确定的值。这是由于每次函数调用结束后存储单元已被释放,下次调用时又重新分配存储单元,而所分配的单元中的值是不确定的。
3)作用域:作用域仍为局部作用域,当定义它的函数或者语句块结束的时候,作用域随之结束,尽管该变量还继续存在,但不能使用它。
【2】static作用的函数
在函数的返回类型前加上关键字static,函数就被定义成为静态函数。
函数的定义和声明默认情况下是extern的,但静态函数只是在声明他的文件当中可见,不能被其他文件所用。只能被本文件中的函数调用,而不能被同一程序其它文件中的函数调用。好处:
1)其他文件中可以定义相同名字的函数,不会发生冲突
2)静态函数不能被其他文件所用。
四、static作用的变量、函数与普通变量和函数区别
【1】static作用的变量与普通变量和函数区别
1)static全局变量与普通的全局变量有什么区别 ?
全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。
全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。
这两者的区别在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。
static全局变量只初使化一次,防止在其他文件单元中被引用;
2)static局部变量和普通局部变量有什么区别 ?
把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。
static局部变量只被初始化一次,下一次依据上一次结果值;
【2】static作用的函数与普通函数有什么区别?
static函数与普通函数作用域不同,仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static修饰的函数),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件.static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝
C语言中static关键字的作用