c语言中static的用法详细示例分析

[复制链接]
2142|29
 楼主| monkeypony 发表于 2015-5-27 22:34 | 显示全部楼层 |阅读模式
static在c里面可以用来修饰变量,也可以用来修饰函数。
先看用来修饰变量的时候。变量在c里面可分为存在全局数据区、栈和堆里。其实我们平时所说的堆栈是栈而不是堆,不要弄混。
 楼主| monkeypony 发表于 2015-5-27 22:34 | 显示全部楼层
代码如下:
  1. int a ;
  2. int main()
  3. {
  4.     int b ;
  5.     int c* = (int *)malloc(sizeof(int));
  6. }

a是全局变量,b是栈变量,c是堆变量。
static对全局变量的修饰,可以认为是限制了只能是本文件引用此变量。有的程序是由好多.c文件构成。彼此可以互相引用变量,但加入static修饰之后,只能被本文件中函数引用此变量。
 楼主| monkeypony 发表于 2015-5-27 22:35 | 显示全部楼层
static对栈变量的修饰,可以认为栈变量的生命周期延长到程序执行结束时。一般来说,栈变量的生命周期由OS管理,在退栈的过程中,栈变量的生命也就结束了。但加入static修饰之后,变量已经不再存储在栈中,而是和全局变量一起存储。同时,离开定义它的函数后不能使用,但如再次调用定义它的函数时,它又可继续使用, 而且保存了前次被调用后留下的值。

static对函数的修饰与对全局变量的修饰相似,只能被本文件中的函数调用,而不能被同一程序其它文件中的函数调用。
 楼主| monkeypony 发表于 2015-5-27 22:35 | 显示全部楼层
文件a.c

代码如下:
  1. static int i; //只在a文件中用
  2. int j;          //在工程里用
  3. static void init()         //只在a文件中用
  4. {
  5. }
  6. void callme()          //在工程中用
  7. {
  8.     static int sum;
  9. }
 楼主| monkeypony 发表于 2015-5-27 22:36 | 显示全部楼层
上面的全局i变量和init()函数只能用在a.c文件中,全局变量sum的作用域只在callme里。变量j和函数callme()的全局限扩充到整个工程文件。所以可以在下面的b.c中用extern关键字调用。extern告诉编译器这个变量或者函数在其他文件里已经被定义了。
 楼主| monkeypony 发表于 2015-5-27 22:36 | 显示全部楼层
文件b.c

代码如下:
  1. extern int j;                    //调用a文件里的
  2. extern void callme();   //调用a文件里的
  3. int main()
  4. {
  5.   ...
  6. }

extern的另外用法是当C和C++混合编程时如果c++调用的是c源文件定义的函数或者变量,那么要加extern来告诉编译器用c方式命名函数:


文件A.cpp调用a.c里面的变量i和函数callme()
 楼主| monkeypony 发表于 2015-5-27 22:37 | 显示全部楼层
代码如下:
  1. extern "C"  //在c++文件里调用c文件中的变量
  2. {
  3.    int j;
  4.    void callme();
  5. }
  6. int main()
  7. {
  8.    callme();
  9. }
 楼主| monkeypony 发表于 2015-5-27 22:37 | 显示全部楼层
二 static法则:
A、若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度;
B、若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度;
C、设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题;
 楼主| monkeypony 发表于 2015-5-27 22:38 | 显示全部楼层
全局变量有外部、静态两种存储方式。
(1)全局变量一般用外部存储方式存储,用保留字extern加以定义。此时,变量的作用域是构成整个程序的所有程序文件,也就是定义的外部变量可供其它程序文件使用。
使用这样的全局变量一定要非常慎重,一旦产生错误,将波及整个程序。
 楼主| monkeypony 发表于 2015-5-27 22:38 | 显示全部楼层
(2)如果希望全局变量仅限于本程序文件使用,而其它程序文件中不能引用,这时必须将其存储方式定义为静态存储方式,用保留字static加以定义。此时称为静态外部变量。
例如,在上例文件filel.c中,如果作这样的定义:
static int a:
则变量a的作用域被缩小至本程序文件filel.c,文件file2.c中不能引用。
值得注意的是对全局变量加static,定义为静态存储方式,并不意味着是静态存储;而不加static,是动态存储。两种形式的全局变量(外部变量)都是静态存储方式,都是编译时分配存储空间,但作用域不同。使用静态外部变量,有利于隔离错误,有利于模块化程序设计。
 楼主| monkeypony 发表于 2015-5-27 22:38 | 显示全部楼层
(3)全局变量的缺省存储方式是外部存储方式。
前面章节中的程序没有见到变量的存储类别定义,实际上采用变量的缺省存储方式。对局部变量采用auto方式,对全局变量采用extern方式。这也是至今为止,我们在程序中没有见到auto、extern等的原因。
 楼主| monkeypony 发表于 2015-5-27 22:38 | 显示全部楼层
至此,我们对变量的存储类别及数据类型进行了全面讨论,在此作个小结。


1.变量定义的一般形式
存储类别数据类型变量表;
 楼主| monkeypony 发表于 2015-5-27 22:39 | 显示全部楼层
2.变量定义的作用
①规定了变量的取值范围。
②规定了变量进行的运行操作。
③规定了变量的作用域。
④规定了变量的存储方式。
⑤规定了变量占用的存储空间。
 楼主| monkeypony 发表于 2015-5-27 22:39 | 显示全部楼层
3.局部变量和全局变量
从作用域角度将变量分为局部变量和全局变量。它们采取的存储类别如下:


局部变量:
①自动变量,即动态局部变量(离开函数,值就消失)。
②静态局部变量(离开函数,值仍保留)。
③寄存器变量(离开函数,值就消失)。
④形式参数可以定义为自动变量或寄存器变量。


全局变量:
①静态外部变量(只限本程序文件使用)。
②外部变量(即非静态的外部变量,允许其它程序文件引用)。
 楼主| monkeypony 发表于 2015-5-27 22:39 | 显示全部楼层
4.动态存储和静态存储
从变量存在时间可将变量存储分为动态存储和静态存储。静态存储是在整个程序运行时都存在,而动态存储则是在调用函数时临时分配存储单元。


动态存储:
①自动变量(函数内有效)。
②寄存器变量(函数内有效)。
③形式参数。


静态存储:
①静态局部变量(函数内有效)。
②静态外部变量(本程序文件内有效)。
③外部变量(整个程序可引用)。
 楼主| monkeypony 发表于 2015-5-27 22:40 | 显示全部楼层
5.静态存储区和动态存储区
从变量值存放的位置可将变量存储区分为静态存储区和动态存储区:
内存中静态存储区:
①静态局部变量。
②静态外部变量。
③外部变量(可被同一程序其它文件引用)。
内存中动态存储区:自动变量和形式参数。
CPU中的寄存器:寄存器变量。
vivilzb1985 发表于 2015-6-8 19:44 | 显示全部楼层
static对全局变量的修饰,可以认为是限制了只能是本文件引用此变量。有的程序是由好多.c文件构成。彼此可以互相引用变量,但加入static修饰之后,只能被本文件中函数引用此变量。
vivilzb1985 发表于 2015-6-8 19:46 | 显示全部楼层
全局变量一般用外部存储方式存储,用保留字extern加以定义。此时,变量的作用域是构成整个程序的所有程序文件,也就是定义的外部变量可供其它程序文件使用。
vivilzb1985 发表于 2015-6-8 19:46 | 显示全部楼层
static对栈变量的修饰,可以认为栈变量的生命周期延长到程序执行结束时。一般来说,栈变量的生命周期由OS管理,在退栈的过程中,栈变量的生命也就结束。
shenmu2012 发表于 2015-6-10 19:39 | 显示全部楼层
static的用法的确多注意的,,用好了可以接上很大的内存空间的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

133

主题

715

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部