C语言与C++中static,extern的用法及区别总结

来源:互联网 发布:python ftp 下载文件 编辑:程序博客网 时间:2024/06/03 19:54

在C语言中:

隐藏

  很多人经常会忘了这一条。其实这个作用很常用也很重要。
  当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性。
  为理解这句话,我举例来说明。我们要同时编译两个源文件,一个是a.c,另一个是main.c。
  

char a = 'A'; // global variablevoid msg() {    printf("Hello\n"); }
int main(void){        extern char a;        printf("%c ", a);    (void)msg();    return 0;}

程序的运行结果是:
A Hello

  为什么在a.c中定义的全局变量a和函数msg能在main.c中使用?
  前面说过,所有未加static前缀的全局变量和函数都具有全局可见性,其它的源文件也能访问。 
  此例中,a是全局变量,msg是函数,并且都没有加static前缀,因此对于另外的源文件main.c是可见的。
  如果加了static,就会对其它源文件隐藏。
  

static char a = 'A'; // global variablestatic void msg() {    printf("Hello\n"); }int main(void){          printf("%c ", a);    (void)msg();    return 0;}

  上面的程序会输出什么呢?
  答案是:报错,找不到a与msg的定义。
  在a和msg的定义前加上static,main.c就看不到它们了。
  利用这一特性可以在不同的文件中定义同名函数和同名变量,而不必担心命名冲突。

  static可以用作函数和变量的前缀,对于函数来讲,static的作用仅限于隐藏。
  在上面的例子中,含有一个新的关键字——extern
  下面来讲一下static和extern的区别:

extern

  extern告诉编译器这个变量或函数在其他文档里已被定义了。

  看下面的例子:
  

static int i; //只在a文档中用int j;    //在工程里用static void init()         //只在a文档中用{}void callme()          //在工程中用{   static int sum;}extern int j;     //调用a文档里的extern void callme();  //调用a文档里的int main(){  ...}

  上面的全局i变量和init()函数只能用在a.c文档中,全局变量sum的作用域只在callme里。变量j和函数callme()的全局限扩充到整个工程文档。所以能够在下面的b.c中用extern关键字调用。extern告诉编译器这个变量或函数在其他文档里已被定义了。

extern C

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

extern "C"  //在c++文档里调用c文档中的变量{   int j;   void callme();}int main(){   callme();}

static法则:

  A、若全局变量仅在单个C文档中访问,则能够将这个变量修改为静态全局变量,以降低模块间的耦合度;
  B、若全局变量仅由单个函数访问,则能够将这个变量改为该函数的静态局部变量,以降低模块间的耦合度;
  C、设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题;

变量

1.变量定义的一般形式

存储类别数据类型变量表;

2.变量定义的作用

①规定了变量的取值范围。
②规定了变量进行的运行操作。
③规定了变量的作用域。
④规定了变量的存储方式。
⑤规定了变量占用的存储空间。

3.局部变量和全局变量

从作用域角度将变量分为局部变量和全局变量。它们采取的存储类别如下:

局部变量:

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

全局变量:

①静态外部变量(只限本程序文件使用)。
②外部变量(即非静态的外部变量,允许其它程序文件引用)。

动态存储和静态存储

  从变量存在时间可将变量存储分为动态存储和静态存储。
  静态存储是在整个程序运行时都存在,而动态存储则是在调用函数时临时分配存储单元。

动态存储:

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

静态存储:

①静态局部变量(函数内有效)。
②静态外部变量(本程序文件内有效)。
③外部变量(整个程序可引用)。

静态存储区和动态存储区

  从变量值存放的位置可将变量存储区分为静态存储区和动态存储区:

内存中静态存储区:

①静态局部变量。
②静态外部变量。
③外部变量(可被同一程序其它文件引用)。

内存中动态存储区:自动变量和形式参数。

CPU中的寄存器:寄存器变量。

全局变量

  全局变量有外部、静态两种存储方式。

外部全局变量

  全局变量一般用外部存储方式存储,用保留字extern加以定义。此时,变量的作用域是构成整个程序的所有程序文件,也就是定义的外部变量可供其它程序文件使用。
  使用这样的全局变量一定要非常慎重,一旦产生错误,将波及整个程序。

静态全局变量

  如果希望全局变量仅限于本程序文件使用,而其它程序文件中不能引用,这时必须将其存储方式定义为静态存储方式,用保留字static加以定义。此时称为静态外部变量。
例如,在文件filel.c中,如果作这样的定义:

static int a:

  则变量a的作用域被缩小至本程序文件filel1.c,文件file2.c中不能引用。
  值得注意的是对全局变量加static,定义为静态存储方式,并不意味着是静态存储;而不加static,是动态存储。
  两种形式的全局变量(外部变量)都是静态存储方式,都是编译时分配存储空间,但作用域不同。使用静态外部变量,有利于隔离错误,有利于模块化程序设计。

全局变量的缺省存储方式是外部存储方式。

  前面章节中的程序没有见到变量的存储类别定义,实际上采用变量的缺省存储方式。对局部变量采用auto方式,对全局变量采用extern方式。这也是至今为止,我们在程序中没有见到auto、extern等的原因。
至此,我们对变量的存储类别及数据类型进行了全面讨论,在此作个小结。

局部静态变量

  在C/C++中, 局部变量按照存储形式可分为三种auto, static, register。其中register不常用到
  下面主要说说auto和static的区别。

  1. 存储空间分配和生存周期不同

auto类型局部变量就是普通的局部变量(不加修饰的局部变量默认为该类型)。该类型局部变量存储在栈上,在动态存储区,生命周期仅限于定义它的函数,函数结束,它就自动释放。static类型局部变量存储在静态存储区,在程序整个运行期间都不释放。两者之间的作用域相同,但生存期不同。
  2. static局部变量在所处模块在初次运行时进行初始化工作,且只操作一次。
  3. 对于局部静态变量,如果不赋初值,编译期会自动赋初值0或空字符,而auto类型的初值是不确定的

  对于C++中的class对象例外,class的对象实例如果不初始化,则会自动调用默认构造函数,不管是否是static类型
  特点: static局部变量的”记忆性”与生存期的”全局性”

外部静态变量/函数

  
  在C语言中 static有了第二种含义:
  用来表示不能被其它文件访问的全局变量和函数。
  但为了限制全局变量/函数的作用域, 函数或变量前加static使得函数成为静态函数。
  但此处“static”的含义不是指存储方式,而是指对函数的作用域仅局限于本文件(所以又称内部函 数)。
  注意此时, 对于外部(全局)变量, 不论是否有static限制, 它的存储区域都是在静态存储区,生存期都是全局的. 此时的static只是起作用域限制作用, 限定作用域在本模块(文件)内部.
  使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名。

静态数据成员/成员函数

前两种C和C++都有,这种仅在C++中有,下面作以下介绍:
  C+ +重用了这个关键字,并赋予它与前面不同的第三种含义:
  表示属于一个类而不是属于此类的任何特定对象的变量和函数.

  这是与普通成员函数的最大区别,也是其应用所在。
  比如在对某一个类的对象进行计数时, 计数生成多少个类的实例,就可以用到静态数据成员。
  在这里面, static既不是限定作用域的, 也不是扩展生存期的作用, 而是指示变量/函数在此类中的唯一性. 这也是”属于一个类而不是属于此类的任何特定对象的变量和函数”的含义.。
  因为它是对整个类来说是唯一的,因此不可能属于某一个实例对象的.
  针对静态数据成员而言, 成员函数不管是否是static, 在内存中只有一个副本, 普通成员函数调用时, 需要传入this指针, static成员函数调用时, 没有this指针。
  
  

0 0
原创粉丝点击