【转】作用域、链接属性、存储类型总结--转载学习,很清晰,很详细

标识符:

首先,在讨论这三种东西之前,详细说明一下C语言中的标识符。

标识符是用户编程为变量、常量、函数、语句等指定的名字,就好比人名一样的东西。

标识符的命名规则如下:

1.只能由字母、数字、下划线组成,并且首字符不能是数字;

2.不能把C语言的关键字作为标识符;

3.对大小写敏感;

其次,需要明确,作用域和链接属性是在标识符范畴内讨论的,存储类型是在标识符中的变量范畴内讨论的。

 

作用域:

标识符的作用域就是程序中该标识符可以被使用的区域,由它的声明位置决定

分为以下四类:

1.文件作用域  2.代码块作用域  3.原型作用域  4.函数作用域

1.文件作用域:

  任何在所有代码块之外声明的标识符(变量、常量、函数名、语句等)具有,这表示这个标识符从它声明的位置到这个源文件结尾处都可以访问。

  注意:在任何代码块之外声明的函数名也具有文件作用域,因为这个函数名本身并不属于任何代码块。

2.代码块作用域:

  位于{}之间的所有语句称为代码块,在代码块内声明的标识符,其作用域为从其声明位置开始到这段代码块结束,它可以被这个区间内的语句访问。

  注意:处于嵌套状态的代码块,当内层和层声明了相同的标识符时,外层这个标识符在内层不再起作用。编程中应该尽量避免出现这种情况。

3.原型作用域:

  只适用于在函数原型中声明的参数名,作用域为函数原型中的()内,为防止在同一个原型中不止一次使用这个名字。

4.函数作用域:

  只用于语句标签。

下面用一个例子说明几种作用域:

#include

int a;                                                       //a具有文件作用域

void test(int *b);                                      //b具有原型作用域

int main(void)

{

  int c=10;                                            //c具有代码块作用域

  a=20;

  printf("a=%d",a);

  printf("Before change: c=%d",c);

  test(&c);

  printf("After change: c=%d",c);

  for(int d=0;d<5;d++)                           //d具有代码块作用域

  {

    int e=0;              //e仅在循环内起作用

    printf("d=%d",d);

  }

  return 0;

}

void test(int *f)              //f具有代码块作用域,在函数声明中起作用

{

  *f=30;

}

 

链接属性:

作用域考虑的是单一源文件的情况,而链接属性是在多源文件范畴内的。链接属性决定如何处理在不同源文件中出现的相同标识符

分为三种:

1.external(外部)  2.internal(内部)  3.none(无)

1.external:无论标识符声明多少次,位于几个源文件内,都表示同一实体;

2.internal:在同一源文件内的所有声明属于同一实体,不同源文件中的多个声明则表示不同实体;

3.none:总是被当做单独的个体,即不同的实体。

注意:

①缺省情况下,具有文件作用域的变量、函数名的链接属性为external,其他为none;

 

用于修改标识符链接属性的关键字:

1.static  2.extern

1.static:用于将external改为internal,如果被修改的标识符不是external,则起不到修改链接属性的作用;

2.extern:

①对于具有文件作用域的标识符,extern加不加都可以;

②当extern再是第一次用于声明标识符,那么它的作用是表示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义;

③具有extern链接属性的实体总是具有静态存储类型。

 

存储类型:

指存储变量值的内存类型,它决定变量的生存期。一般变量的存储类型取决于声明的位置。

分为三种:

1.静态(static)变量:在任何代码块之外声明的变量,存储于静态内存中,在程序运行之前创建,并在程序执行期间始终存在;

2.自动(automatic)变量:在代码块内部声明的变量默认为自动变量,存储于堆栈中,当程序执行代码块时才被创建,代码块执行结束时自动销毁;

  默认为自动变量的原因:

  ①当需要时再分配内存,减少内存的总需求量;

  ②有效实现递归。

3.寄存器(register)变量:用于声明存储于寄存器中的自动变量;将使用频率较高的变量放入硬件寄存器,可以提高效率。

 

关于static的两点说明:


1.当static用来修饰函数定义、代码块之外的变量声明时,用于修改其链接属性,从external->internal,不改变作用域和存储类型(有表示“本地”之意);

2.当作用于代码块内部的变量声明时,用于修改变量的存储类型,从auto->static,不改变作用域和链接属性。

posted @ 2016-05-03 21:05  L_free  阅读(303)  评论(0编辑  收藏  举报