作用域
当变量被定义在程序的不同位置时,它的作用范围是不一样的,这个作用范围就是我们所说的作用域。
C语言编辑器可以确认不同类型的作用域:
-代码块作用域
-文件作用域
-原型作用域
-函数作用域
代码块作用域
在代码块中定义的变量,具有代码块作用域。作用范围是从变量定义的位置开始,到标志该代码块结束的右大括号(})处。
尽管函数的形式参数不在大括号内定义,但其同样具有代码块作用域,隶属于包含函数体的代码块。
文件作用域
任何在代码块之外声明的标识符都具有文件作用域,作用范围是从他们声名位置开始,到文件结尾处都是可以访问的。
另外,函数名也具有文件作用域,因为函数名本身也是在代码块之外。
原型作用域
原型作用域只适用于那些在函数原型中声明的参数名。函数在声明的时候可以不写参数的名字(但参数类型是必须要写上的),其实函数原型的参数名还可以随便写一个名字,不必与形式参数相匹配(当然,这样做没有任何意义)。
函数作用域
函数作用域只适用于goto语句的标签,作用将goto语句的标签限制在同一个函数内部,以及防止出现重名标定义和声明
当一个变量被定义的时候,编译器为变量申请内存空间并填充一些值。
当一个变量被声明的时候,编译器就知道该变量被定义在其他地方。
声明是通知编译器该变量名及相关的类型已存在,不需要再为此申请内存空间。
局部变量既是声明又是定义。
定义只能来一次,否则就叫做重复定义某个同名变量;而声名可以有很多次。
链接属性
external(外部的)
-多个文件中声明的同名标识符表示同一个实体
internal(内部的)
-单个文件中声明的同名标识符表示同一个实体
none(无)
-声明的同名标识符被当作独立不同的实体
只有具备文件作用域的标识符才能拥有external或internal的链接属性,其他作用域的标识符都是none属性。
默认情况下,具备文件作用域的标识符拥有external属性。也就是说该标识符允许跨文件访问。对于external属性的标识符,无论在不同文件中声明多少次,表示的都是同一个实体。
使用static关键字可以使得原先拥有external属性的标识符变为intennal属性。这里有两点需要注意:
-使用static关键字修改链接属性,只对具有文件作用域的标识符生效(对于拥有其他作用域的标识符是另一种功能)
-链接属性只能修改一次,也就是说一旦将标识符的链接属性变为internal,就无法变回external了
生存期和存储类型
生存期
C语言的变量拥有两种生存期
-静态存储期
-自动存储期
具有文件作用域的变量属于静态存储期,函数也属于静态存储期。属于静态存储期的变量在程序执行期间将一直占据存储空间,知道程序关闭才释放。
存储类型
存储类型其实是指存储变量值的内存类型,C语言提供了5种不同的存储类型:
-auto
-register
-static
-extern
-typedef
自动变量(auto)
在代码块中声明的变量默认的存储类型就是自动变量,使用关键字auto来描述。
寄存器变量(register)
讲一个变量声明为寄存器变量,那么该变量就有可能被存放于CPU的寄存器中。
寄存器变量和自动变量在很多方面都是一样的,它们都拥有代码块作用域,自动存储器和空链接属性。
不过这里有一点需要注意的是:当你将变量声明为寄存器变量,那么你就没办法通过取址运算符获得该变量的地址。
静态局部变量(static)
使用static来声明局部变量,那么就可以将局部变量指定为静态局部变量。
static使得局部变量具有静态存储期,所以它的生存期与全局变量一样,直到程序结束才释放。