C语言中static关键字的作用

C语言中static关键字的作用

华清远见2014-10-05   北京海淀区 张俊浩

一、C源程序编译后的可执行文件(elf)存储空间布局

C语言中static关键字的作用_第1张图片

1)正文段——CPU执行的机器指令部分;一个程序只有一个副本;只读,防止程序由于意外事故而修改自身指令;

2)初始化数据段(数据段)——在程序中所有赋了初值的全局变量,存放在这里。

3)非初始化数据段(bss段)——在程序中没有初始化的全局变量;内核将此段初始化为0。

4)栈——增长方向:自顶向下增长;自动变量以及每次函数调用时所需要保存的信息(返回

地址,局部变量,环境信息)。

5)堆——动态存储分。是向高地址扩展的数据类型,是自下向上的扩展方式。

二、C语言中的变量存储类型 

存储说明符autoregisterexternstatic,对应两种存储期模式:自动存储期和静态存储期。

autoregister对应自动存储期。具有自动存储期的变量在进入声明该变量的程序块时被建立,它在该程序块活动时存在,退出该程序块时撤销。

关键字externstatic用来说明具有静态存储期的变量和函数。用static声明的局部变量具有静态存储持续期(static storage duration),或静态范围(static extent)。虽然他的值在函数调用之间保持有效,但是其名字的可视性仍限制在其局部域内。静态局部对象在程序执行到该对象的声明处时被首次初始化。

auto 

    auto称为自动变量 如果函数不做其他说明的话 均为自动变量

static 

    static称为静态变量。根据变量的类型可以分为静态局部变量和静态全程变量。【详见四、C语言中static关键字的作用】 

extern 

    extern称为外部变量。为了使变量除了在定义它的源文件中可以使用外, 还要被其它文件使用。因此,   必须将全程变量通知每一个程序模块文件,   此时可用extern来说明。

register 
    register称为寄存器变量。它只能用于整型和字符型变量。定义符register说明的变量被Turbo C2.0存储在CPU的寄存器中,  而不是象普通的变量那样存储在内存中, 这样可以提高运算速度。但是Turbo C2.0只允许同时定义两个寄存器变量,一旦超过两个, 编译程序会自动地将超过限制数目的寄存器变量当作非寄存器变量来处理。因此, 寄存器变量常用在同一变量名频繁出现的地方。


三、生存周期

(1)局部变量在每次函数调用的时候分配空间,在函数调用结束之后销毁。

(2)全局变量在程序开始运行时分配空间,在程序结束时销毁。

(3)如果局部变量和全局变量重名,局部变量会暂时覆盖掉全局变量。

(4)全局变量只能用常量表达式初始化,因为程序开始运行时要用适当的值来初始化全局变量,所以初始值必须保存在编译生成的可执行文件中,因此初始值在编译时要计算出来。c语言从语法上规定,全局变量只能用常量表达式初始化

 

四、C语言中static关键字的作用

1static作用的变量

1.static修饰全局变量:在全局变量前加static,全局变量就被定义成为一个全局静态变量。

特点如下:

1)存储区(内存中的位置):静态存储区没变(静态存储区在整个程序运行期间都存在);

2)初始化:未经初始化的全局静态变量会被程序自动初始化为0。(自动对象的值是任意的,除非他被显示初始化)

3)作用域:全局静态变量在声明他的文件之外是不可见的。准确地讲从定义之处开始到文件结尾。非静态全局 变量的作用域是整个源程序(多个源文件可以共同使用); 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。好处:   

1)不会被其他文件所访问,修改;

2)其他文件中可以使用相同名字的变量,不会发生冲突。

 

2.static修饰局部变量:在局部变量之前加上关键字static,局部变量就被定义成为一个局部静态变量。特点如下:

1) 存储区(内存中的位置):由栈变为静态存储区(初始化的局部静态变量存放在.data段,未初始化的局部静态变量存放在.bss段),生存期为整个源程序,只能在定义该变量的函数内使用。退出该函数后,尽管该变量还继续存在,但不能使用它;

2)初始化:为静态局部变量赋初值是在编译时进行的,即只赋初值一次,在程序运行时它已有初值。以后每次调用函数时不再重新赋初值而只是保留上次函数调用结束时的值。而为自动变量赋初值,不是在编译时进行的,而是在函数调用时进行,每调用函数重新给一次值,相对于执行一次赋值语句。如果在定义局部变量是不赋初值的话,对静态局部变量来说,编译时自动赋初值0(对数值型变量)或空字符(对字符型变量)。而对自动变量来说,如果不赋初值,则它的值是不确定的值。这是由于每次函数调用结束后存储单元已被释放,下次调用时又重新分配存储单元,而所分配的单元中的值是不确定的。

3)作用域:作用域仍为局部作用域,当定义它的函数或者语句块结束的时候,作用域随之结束,尽管该变量还继续存在,但不能使用它。

 

2static作用的函数

 在函数的返回类型前加上关键字static,函数就被定义成为静态函数。

 函数的定义和声明默认情况下是extern的,但静态函数只是在声明他的文件当中可见,不能被其他文件所用。只能被本文件中的函数调用,而不能被同一程序其它文件中的函数调用。好处:

1)其他文件中可以定义相同名字的函数,不会发生冲突

2)静态函数不能被其他文件所用。

 

五、static作用的变量、函数与普通变量和函数区别

1static作用的变量普通变量和函数区别

 

1)static全局变量与普通的全局变量有什么区别 ?

全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。

全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。

Turbo C2.0允许将大型程序分成若干独立模块文件分别编译, 然后将所有模块的目标文件连接在一起, 从而提高编译速度, 同时也便于软件的管理和维护。静态全程变量就是指只在定义它的源文件中可见而在其它源文件中不可见的变量。

这两者的区别在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,程变量可以再说明为外部变量(extern), 被其它源文件使用, 非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效,不能再被说明为外部的,在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。 

static全局变量只初使化一次,防止在其他文件单元中被引用

  

2)static局部变量和普通局部变量有什么区别 ?

把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。  

static局部变量只被初始化一次,下一次依据上一次结果值;

   

2static作用的函数与普通函数有什么区别?

 

static函数与普通函数作用域不同,仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static修饰的函数),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件.static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝

 

你可能感兴趣的:(C语言进阶)