CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  C语言

extern & static 在C语言中的用法

楼主licalig(去何从)2006-03-02 13:32:35 在 C/C++ / C语言 提问

好难理解这两个限定符。请大家指点指点。  
  这两个限定符有什么用途,用它们有什么好处?  
  先谢谢了! 问题点数:100、回复次数:15Top

1 楼dragonzxh(河马MiaMia~柯奶奶和黑爷爷的儿子叫柯南...~)回复于 2006-03-02 13:34:47 得分 50

来本文只是本人对C++中关于静态类型的一个总结,如错误之处,请大家帮我改正。我分两个方面来总结,第一方面主要是相对于面向过程而言,即在这方面不涉及到类,第二方面相对于面向对象而言,主要说明static在类中的作用。  
  一、在面向过程设计中的static关键字  
  1、静态全局变量  
  定义:在全局变量前,加上关键字   static   该变量就被定义成为了一个静态全局变量(即全局静态变量)。全局静态变量使得该变量成为定义该变量的源文件所独享,也即静态变局变量对组成该程序的其他源文件是无效的。具体例子可见C++程序设计教程P103  
  特点:  
    A、该变量在全局数据区分配内存。  
    B、初始化:如果不显式初始化,那么将被隐式初始化为0。  
    C、访变量只在本源文件可见,严格的讲应该为定义之处开始到本文件结束。    
    例(摘于C++程序设计教程---钱能主编P103):    
          //file1.cpp              
          #include<iostream.h>  
          void   fn();  
          extern   int   n;  
          void   main()  
          {  
            n=20;  
            cout   <<   n   <<   endl;  
            fn();  
          }    
          //file2.cpp  
          #include<iostream.h>  
          static   int   n;   //定义静态全局变量,初始化为0;  
          void   fn()  
          {  
            n++;  
            cout   <<   n   <<   endl;  
          }  
    文件分别编译能通过,但连接时file1.cpp   中的变量n找不到定义,产生连接错误。  
  使一个变量只在源文件中全局使用有时是必要的。  
  第一, 不必担心另外源文件使用它的名字,该名字在源文件中是唯一的。  
  第二, 源文件的全局变量不能被其他源文件所用,不能被其他的源文件所修改,保证变量的值是可靠的。  
    D、文件作用域下声明的const的常量默认为static存储类型。  
  2、静态局部变量  
  定义:在局部变量前加上static关键字时,就定义了静态局部变量。  
  特点:  
    A、该变量在全局数据区分配内存。  
    B、初始化:如果不显式初始化,那么将被隐式初始化为0。  
    C、它始终驻留在全局数据区,直到程序运行结束。但其作用域为局部作用域,当定义它的函数或语句块结束时,其作用域随之结束。  
   
  我的简单理解是这样的:    
  当static用来修饰局部变量时,它就改变了局部变量的存放位置,将其由原来的栈中存放改为全局静态储存区,但是没有改变变量的作用域,还是局限在局部的{}里。    
  当static用来修饰全局变量时,它就改变了全局变量的作用域,使其不能被别的程序extern,限制在了当前文件里,但是没有改变其存放位置,还是在全局静态储存区。    
  3、静态函数(注意与类的静态成员函数区别)  
  函数的定义和声明默认情况下在整个程序中是extern的,有时候可能需要使某个函数只在一个源文件中有效,不能被其他源文件所用,这时在函数前面加上static.  
  定义:在函数的返回类型前加上static关键字,函数即被定义成静态函数。  
  特点:  
    A、静态函数只能在本源文件中使用(这是与普通函数区别)  
    例(摘于C++程序设计教程---钱能主编P103):              
            //file1.cpp  
          void   fn();  
          void   staticFn()  
          void   main()  
          {  
            fn();  
            staticFn();  
          }  
          //file2.cpp  
          #include<iostream.h>  
          static   void   staticFn();  
          void   fn();  
          void   fn()  
          {  
            staticFn();  
            cout   <<   "this   is   fn()   \n";  
          }  
          void   staticFn()  
          {  
            cout   <<   "this   is   staticFn()   \n";  
          }              
  连接时,将产生找不到函数staticFn()定义的错误。  
  作用:  
  第一, 它允许其他源文件建立并使用同名的函数,而不相互冲突  
  第二, 声明为静态的函数不能被其他源文件所调用,因为它的名字不能得到,  
  B、主意事项  
    在文件作用域下声明的inline函数默认为static类型。  
   
  另其它::  
  C语言中提供了存储说明符auto,register,extern,static说明的四种存储类别。四存储类别说明符有两种存储期:自动存储期和静态存储期。其中auto和register对应自动存储期。具有自动存储期的变量在进入声明该变量的程序块是被建立,它在该程序块活动时存在,退出该程序块时撤销。  
  关键字extern和static用来说明具有静态存储期的变量和函数。用static声明的局部变量只能被定义该变量的函数所识别,但是不同于自动变量的是,static变量在其函数被调用退出后,仍保留其值。下次函数被调用时,可以访问最近一次被修改后的值。static变量的声明方法如下:  
  static int si   =   1;  
  由于static的以上特性,可以实现一些特定的功能。下面说明常见的两种用途。  
  1.   统计函数被调用的次数  
  声明函数的一个局部变量,并设为static类型,作为一个计数器,这样函数每次被调用的时候就可以进行计数。这是统计函数被调用次数的最好的办法,因为这个变量是和函数息息相关的,而函数可能在多个不同的地方被调用,所以从调用者的角度来统计比较困难。测试代码如下:  
  /*-------------------------------------------------------------------  
  s_fun.c     to   count   the   number   of   a   function's   being   called,   use   static   var.  
  */  
    #include   <stdio.h>  
    int   fun_1(int);  
    int   main()  
  {  
  int   i;  
  for   (i   =   1;   i   <=   5;   i++)  
  fun_1(i);  
    return   0;  
  }  
    int   fun_1(int   x)  
  {  
  static   count   =   0;  
  count++;  
  printf("I   have   been   called   %d   times.\n",   count);  
   
  return   2*x;  
  }  
  输出结果为:  
  I   have   been   called   1   times.  
  I   have   been   called   2   times.  
  I   have   been   called   3   times.  
  I   have   been   called   4   times.  
  I   have   been   called   5   times.  
    2.   减少局部数组建立和赋值的开销  
  变量的建立和赋值是需要一定的处理器开销的,特别是数组等含有较多元素的存储类型。在一些含有较多的变量并且被经常调用的函数中,可以将一些数组声明为static类型,以减少建立或者初始化这些变量的开销。示例代码如下:  
  /*--------------------------------------------------------------  
  array_1.c to   test   static   array  
  */  
    #include   <stdio.h>  
  #include   <time.h>  
  #include   <string.h>  
    #define   ARRAY_SIZE   10000  
  #define   CALL_TIMES 30000  
    int   fun_1();  
  int   fun_2();  
    int   main()  
  {  
  int   i;  
  char   string2[10],   *string3;  
  time_t t;  
  time(&t);  
  string3   =   ctime(&t);  
  printf("time   1:   %s",   string3);  
   
  for   (i   =   1;   i   <=   CALL_TIMES;   i++)  
  {  
  fun_1();  
  }  
  time(&t);  
  string3   =   ctime(&t);  
  printf("time   2:   %s",   string3);  
   
  for   (i   =   1;   i   <=   CALL_TIMES;   i++)  
  {  
  fun_2();  
  }  
  time(&t);  
  string3   =   ctime(&t);  
  printf("time   3:   %s",   string3);  
   
  return   0;  
  }  
    int   fun_1()  
  {  
  int   a[ARRAY_SIZE],   b[ARRAY_SIZE];  
  int   i,   t;  
   
  for   (   i   =   0;   i   <   ARRAY_SIZE;   i++)  
  {  
  a[i]   =   i;  
  b[i]   =   ARRAY_SIZE   -   i;  
  }  
   
  for   (   i   =   0;   i   <   ARRAY_SIZE;   i++)  
  {  
  t   =   a[i];  
  a[i]   =   b[i];  
  b[i]   =   t;  
  }  
   
  return   0;  
  }  
     
  int   fun_2()  
  {  
  static   int   a[ARRAY_SIZE],   b[ARRAY_SIZE];  
  int   i,   t;  
   
  for   (   i   =   0;   i   <   ARRAY_SIZE;   i++)  
  {  
  a[i]   =   i;  
  b[i]   =   ARRAY_SIZE   -   i;  
  }  
   
  for   (   i   =   0;   i   <   ARRAY_SIZE;   i++)  
  {  
  t   =   a[i];  
  a[i]   =   b[i];  
  b[i]   =   t;  
  }  
   
  return   0;  
  }  
   
  二、面象对象中的static关键字(主要指类中的static关键字)  
  1、静态数据成员  
  特点:  
    A、内存分配:在程序的全局数据区分配。  
    B、初始化和定义:  
     a、静态数据成员定义时要分配空间,所以不能在类声明中定义。  
     b、为了避免在多个使用该类的源文件中,对其重复定义,所在,不能在类的头文件中定义。    
     c、静态数据成员因为程序一开始运行就必需存在,所以其初始化的最佳位置在类的内部实现。  
    C、特点  
     a、对相于   public,protected,private   关键字的影响它和普通数据成员一样,    
     b、因为其空间在全局数据区分配,属于所有本类的对象共享,所以,它不属于特定的类对象,在没产生类对象时其作用域就可见,即在没有产生类的实例时,我们就可以操作它。  
   
    D、访问形式  
     a、   类对象名.静态数据成员名  
     b、   类类型名::   静态数据成员名  
    E、静态数据成员,主要用在类的所有实例都拥有的属性上。比如,对于一个存款类,帐号相对   于每个实例都是不同的,但每个实例的利息是相同的。所以,应该把利息设为存款类的静态数据成员。这有两个好处,第一,不管定义多少个存款类对象,利息数据成员都共享分配在全局区的内存,所以节省存贮空间。第二,一旦利息需要改变时,只要改变一次,则所有存款类对象的利息全改变过来了,因为它们实际上是共用一个东西。  
  2、静态成员函数  
  特点:  
    A、静态成员函数与类相联系,不与类的对象相联系。  
    B、静态成员函数不能访问非静态数据成员。原因很简单,非静态数据成员属于特定的类实例。  
   
  作用:  
    主要用于对静态数据成员的操作。  
  调用形式:  
    A、类对象名.静态成员函数名()  
    B、类类型名::   静态成员函数名()  
  Top

2 楼dragonzxh(河马MiaMia~柯奶奶和黑爷爷的儿子叫柯南...~)回复于 2006-03-02 13:35:27 得分 0

extern嘛就是一个声明.extern后面的已经在别的地方被声明过,Top

3 楼syd1207(既然选择远方,便只顾风雨兼程。。。)回复于 2006-03-02 13:38:52 得分 10

static   就是在本地声明了,只能在本地使用  
  extern   就是别的地方也声明Top

4 楼du51(郁郁思扬)回复于 2006-03-02 14:18:18 得分 10

我觉得extern是为了跨文件域.  
  static是为了占满整个文件.Top

5 楼goodluckyxl(被人遗忘的狗)回复于 2006-03-02 14:20:51 得分 10

static   作用只在文件内部,不具有外部联接  
  而extern与具有外部联接的内容产生关联Top

6 楼iamcaicainiao(老菜,长征)回复于 2006-03-02 14:24:05 得分 0

it's   great.   up   all.Top

7 楼jixingzhong(瞌睡虫·星辰)回复于 2006-03-02 14:45:09 得分 0

extern   全局化,和程序的其他部分共享变量等  
   
  static   本地化,禁止其他部分的访问,防止意外操作。  
                对于单个变量,还有保持静态的意思,让变量空间不释放,一直保存其内部的值Top

8 楼jixingzhong(瞌睡虫·星辰)回复于 2006-03-02 14:49:59 得分 20

好处:  
   
  extern     在大的工程中,不可能所有的内容在一个程序文件中,如果分割成多个文件,那么就不可能保证(一般情况下,特殊的不考虑)所有有调用关系的函数等在一个文件内,这个时候,就需要使用extern来外部申明,使函数等全局化。  
   
  static     对于变量来说,保存值是它的目的,防止重复的计算。  
                  另外的功能就是局部的限制作用,在可能的情况下,一些意外的操作可能对一些数据产生影响,导致整个任务失败。而使用   static   限制就可以防止这中情况。Top

9 楼alen_ghl(东方求*)回复于 2006-03-02 14:57:34 得分 0

鄙视   河马  
  贴那么长贴,眼睛都看疼了!!!Top

10 楼duduhaha(三人行必有我师)回复于 2006-03-02 15:01:21 得分 0

顶楼上的!呵呵.  
  楼主多google一下.  
  Top

11 楼dragonzxh(河马MiaMia~柯奶奶和黑爷爷的儿子叫柯南...~)回复于 2006-03-02 15:03:37 得分 0

长吗?还好啊~Top

12 楼steedhorse(晨星)回复于 2006-03-02 15:22:30 得分 0

不长不长,1024×768的分辩率下翻8页就看完了。。。。Top

13 楼cxc014(有心插柳柳不活,无心栽花花开花?)回复于 2006-03-02 15:25:20 得分 0

幸好的我的是1280*1024是翻了6.4页.....Top

14 楼licalig(去何从)回复于 2006-03-02 17:24:28 得分 0

感谢河马!  
  谢谢大家了!  
  谢谢啊……^_^  
  Top

15 楼YUKIKING()回复于 2006-03-03 09:02:27 得分 0

看看c语言书,不就知道了Top

相关问题

  • extern "C" _declspec(dllimport)用法 谢谢了!!!!!
  • C++用法探讨。
  • C#中as的用法
  • dev c++的用法
  • C#接口用法
  • C#中with的用法?
  • C++高手们,谁能讲一下extern的用法?
  • 请教在C++中static方法的用法有什么特别之处吗?
  • c++里hashtable的用法
  • Borland C++ free command 的用法

关键词

  • c++程序设计
  • 变量
  • 初始化
  • 全局
  • 静态
  • 定义
  • 源文件
  • cout
  • fun
  • void fn

得分解答快速导航

  • 帖主:licalig
  • dragonzxh
  • syd1207
  • du51
  • goodluckyxl
  • jixingzhong

相关链接

  • C/C++ Blog
  • C/C++类图书
  • C/C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo