C语言中一个重要的东西就是弄清申明变量的类型、作用域、存储类型、链接属性等,例如是整型还是浮点型,存储于普通内存还是堆栈或者寄存器,作用于全局还是局部,能否被其他文件 引用等。
链接属性
申明变量或函数时需要标识符,标识符的链接属性一共有三种:external(外部)
, internal(内部)
, none(无)
,external和internal常用,none表示无链接属性,该标识符的多个申明被当成独立不同的实体。
顾名思义,external表示能被其它源文件访问的变量或函数,internal则不能被其它源文件访问,并且缺省情况下代码块(block)外部的变量为external属性,也就是外部变量,代码块内部的变量为internal属性,即局部变量.
如果需要改变链接属性需要使用 extern
和 static
关键字,extern
是转化为external属性,static
是转化为internal属性。
举例说明:
1 |
|
注意上面指出的代码块内部和外部,定义的函数的花括号之外叫做代码块外部,之内叫做代码块内部。
代码块外部缺省为extern
,并且代码块外部使用extern
表示被其它源文件访问,代码块内部使用extern
表示访问其它文件的外部变量。
存储类型
存储类型指申明的变量将被存储到什么地方去,并且与其存储周期有关,就是这个变量何时被创建,何时被销毁,保持多久。
存储类型有三种:
静态变量(static
) —> 存储于普通内存。
自动变量(auto
) —> 存储于堆栈。
寄存器变量(register
) —> 存储于寄存器。
静态变量
任何代码块之外定义的变量,总是处于静态内存中,无需使用 static
关键字,在程序运行之前创建,程序整个执行期间始终存在。
自动变量
代码块内部申明的变量,并且缺省情况下都是(auto
)类型,所以很少使用,存储于堆栈中,程序执行到申明变量处被创建,离开后被销毁,每次在堆栈中占据的内存位置都可能不同。
寄存器变量
用于申明自动变量,即在代码块内部使用,使这类变量存储于寄存器中,寄存器中的变量比内存中的变量访问效率更高。
但是,如果有太多变量申明为 register
,只会选取前几个存储于寄存器中,其它处理为普通自动变量。
通常把使用频率最高的变量申明为寄存器变量,或者指针申明为寄存器变量,以提高效率。例如可以把函数的形参申明为寄存器变量(有可能它节省的时间空间开销抵不上复制这几个值的开销)。
综合举例
1 |
|
初始化
静态变量在不指定初始值的时候,初始化为 0
;
自动变量是否初始化赋值,并无效率的改变(每次执行都要重新初始化),这也是它的优点:可以用任何“表达式”作为初始值。例如:
int add(int a)
{
int b = a + 1; /* 将表达式 a + 1 的值初始化给 b */
return b;
}
注意
static
申明函数或代码块之外的变量时,只修改链接属性 ``external为
internal`,存储类型和作用域不变。static
申明代码块内部变量时,将自动变量修改为静态变量,但是链接属性和作用域不变。
综合举例
1 |
|