目录

首先来声明几个概念:

存储类说明符:

auto register static extern typedef

类型说明符:

void  char  short  int  long  float  double  
signed  unsigned  结构或联合说明符  
枚举说明符  类型定义名

类型限定符:

const volatile

存储类

存储类分为两类:自动存储类(automatic)和静态存储类(static)。声明对象时使用的一些关键字和声明的上下文共同决定了对象的存储类。自动存储类对象对于一个程序块来说是局部的,在退出程序块时该对象将消失。如果没有使用存储类说明符,或者使用了auto限定符,则程序块中的声明生成的都是自动存储类对象。声明为register的对象也是自动存储类对象,暗示了声明的对象将被频繁地访问。只有很少的对象被真正存放在在机器的快速寄存器中,并且只有特定的类型才可以。被声明为register的对象不能对它应用元运算符&。

静态对象可以是某个程序块的局部对象,也可以是所有程序块的外部对象。无论是哪一种情况,在退出和再进入函数或程序块时其值将保持不变。静态变量只在第一次进入程序块时被初始化一次。在一个程序块(包含提供函数代码的程序块)内,静态对象用关键字static声明。在所有程序块外部声明且与函数定义在同一级的对象总是静态的。可以通过static关键字将对象声明为某个特定翻译单元的局部对象,这种类型的对象将具有内部链接。当省略显示的存储类或通过关键字extern进行声明时,对象对整个程序来说是全局可访问的,并且具有外部连接。函数内部的extern声明表明,被声明的对象的存储空间定义在其他地方。

作用域规则

名字的作用域指的是程序中可以使用该名字的部分。对于在函数开头声明的自动变量来说,其作用域是声明该变量的函数。不同函数中声明的具有相同名字的各个局部变量之间没有任何关系。函数的参数实际上可以看做是局部变量。

外部变量或函数的作用域从声明它的地方开始,到其所在的(带编译)的文件的末尾结束。

另一方面,如果要在外部变量的定义之前使用该变量,或外部变量的定义与变量的使用不在同一个源文件中,则必须在相应变量声明中强制性地使用关键字extern。

将外部变量的声明与定义严格区分开来很重要。变量声明用于说明变量的属性(主要是变量的类型),而变量定义除此以外还将引起存储器的分配。

在一个源程序的所有源文件中,一个外部变量只能在某个文件中定义一次,而其他文件可以通过extern声明来访问它(定义外部变量的源文件中也可以包含对该外部变量的extern声明)。外部变量的定义中必须指定数组的长度,但extern声明则不一定要指定数组的长度。

用static声明限定外部变量与函数,可以将其后声明的对象的作用域限定为被编译源文件的剩余部分。通过static限定外部对象,可以达到隐藏外部对象的目的。static类型的内部变量是一种只能在某个特定函数中使用但一直占据存储空间的变量。

外部变量的初始化只能出现在其定义中。

在一个好的程序设计风格中,应该避免出现变量名隐藏外部作用域中相同名字的情况,否则,很可能引起混乱和错误。

初始化

声明对象时,对象的初始化声明符可以为其指定一个初始值。初值紧跟在运算符=之后,它可以是一个表达式,也可以是嵌套在花括号中的初值序列。初值序列可以以逗号结束,这样可以使格式简洁美观。

如果变量不是自动变量,则只能进行一次初始化操作,从概念上讲,应该是在程序开始执行之前进行,并且初始化表达式必须为常量表达式。每次进入函数或程序块时,显式初始化的自动变量都将被初始化一次,其初始化表达式可以是任何表达式。

对静态对象或数组而言,初值中的所有表达式必须是常量表达式。如果初值是用花括号括起来的初值表,则对auto或register类型的对象或数组来说,初值中的表达式也同样必须是常量表达式。但是自动对象的初值是一个单个的表达式,则它不必是常量表达式,但必须符合对象赋值的类型要求。

未显示初始化的静态对象将被隐式初始化,其效果等同于它(或它的成员)被赋以常量0。未显示初始化的自动对象的初始值没有定义。

指针或算数类型对象的初值是一个单个的表达式,也可能扩在花括号中。该表达式将被赋值给对象。

结构的初值可以是类型相同的表达式,也可以是扩在花括号中的按其成员次序排列的处置表。无名的位字段成员将被忽略,因此不被初始化。如果表中的初值的数目比结构的成员数少,则后面余下的结构成员将被初始化为0。初值的数目不能比成员数多。

数组的初值是一个括在花括号中的、由数组成员的初值构成的表。如果数组大小未知,则初值的数目将决定数组的大小,从而使数组类型成为完整类型。若数组大小固定,则初值的数目不能超过数组成员的数目。如果初值数目比数组成员数目少,则尾部余下的数组成员将被初始化为0。

联合的初值可以是类型相同的单个表达式,也可以是括在花括号中的联合的第一个成员的初值。