标识符:编程
首先,在讨论这三种东西以前,详细说明一下C语言中的标识符。函数
标识符是用户编程为变量、常量、函数、语句等指定的名字,就比如人名同样的东西。spa
标识符的命名规则以下:递归
1.只能由字母、数字、下划线组成,而且首字符不能是数字;内存
2.不能把C语言的关键字做为标识符;作用域
3.对大小写敏感;原型
其次,须要明确,做用域和连接属性是在标识符范畴内讨论的,存储类型是在标识符中的变量范畴内讨论的。编译器
做用域:编译
标识符的做用域就是程序中该标识符能够被使用的区域,由它的声明位置决定。test
分为如下四类:
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,不改变做用域和连接属性。