本文只作为个人防止忘记,作为基础资料来查阅所用。
一、变量类型
externel和internal简介:
internel用于描述定义在函数内部的函数变元和变量。外部变量在函数外部定义,故可以在很多函数中使用。由于C语言不允许在一个函数中定义其他函数,因此函数本身是外部的。缺省情况下,外部变量和函数具有如下性质:所有通过名字对外部变量和函数的引用都是引用同一个对象(即外部链接)。
由于外部变量是可以全局访问的,这就为在函数之间交换数据提供了一种可以代替函数变元与返回值的方法。任何函数都可以用名字来访问外部变量,只要这个名字在某个地方已经做了说明。但是使用太多的外部变量,会导致对代码结构产生不好的影响,而且可能会使程序在各个函数之间产生太多的数据联系。
外部变量的用途还表现在他们比内部变量有更大的作用域和更长的生存周期。
1、自动变量(auto)
自动变量只能在函数内部使用,当其所在函数开始调用时开始存在,当函数退出时消失。
作用域规则:说明该自动变量的函数。对于函数参数也是如此,函数参数可看作局部变量。
2、静态变量(static)
存储机制:静态存储。
static说明适用于外部变量和函数时,用于把这些对象的作用域限定为被编译源文件的剩余部分。
static说明适用于内部变量时,和自动变量一样只能在该函数内部使用,但是与自动变量不同的是,不管其所在函数是否被调用,它都是一直存在的。即内部静态变量是一种只能在某一函数内部使用的但一直占据存储空间的变量。
3、寄存器变量(register)
register说明用于提醒编译程序所说明的变量在程序中使用频率较高。其思想是,将寄存器变量放在机器的寄存器中,这样使程序更小、执行速度更快。但编译程序可以忽略此选项。
寄存器说明只适用于自动变量以及函数的形式参数。
4、外部变量(extern)
外部变量是永久保存的,他们的值在从一次函数调用到下次函数调用之间保持不变。因此如果两个函数必须共享某些数据,而且这两个函数有互不调用对方,那么把这些共享数据作为外部变量表示,比用函数变元更好。
作用域规则:从其说明处开始,一直到其所在的被编译的文件的末尾。函数的作用域也是如此。另外,如果一个外部变量在定义之前就要被用到,或者这个外部变量定义在与所要使用的它的源文件不相同的源文件中,那么要在相应的变量说明中强制性使用关键字extern。
将对外部变量的说明与定义严格区分开来非常重要,变量说明用于通报变量的性质(主要是变量的类型),而变量定义则除此以外还引起存储分配。
例:如果在函数的外部有如下说明:
int sp;
double val[MAX_PATH];
则这两个说明定义了两个外部变量sp和val,并为之分配了存储空间,同时也用作源文件其他部分使用的说明。
而:
extern int sp;
extern double val[MAX_PATH];
则:为源文件剩余部分说明了两个外部变量,但是这两个说明并没有建立变量或为他们分配存储空间。
在一个源程序的所有源文件中对一个外部变量只能在某个文件中定义一次,而其他文件可以通过extern说明来访问它。在外部变量的定义中必须指定数组的大小,但在extern说明中,则不一定要指定数组的大小。
外部变量的初始化只能出现在其定义中。
二、变量的初始化
在没有显式初始化的情况下,外部变量和静态变量都被初始化为0。而自动变量和寄存器变量的初始值则没有定义。
在定义纯量变量时,可以通过在所定义的变量名后面加一个“=”和一个表达式进行初始化。如:
int i = 1;
对于外部变量和局部变量,初始化符必须是常量表达式,初始化只作一次(从概念上讲是在程序开始执行之前进行初始化)。
对于自动变量和寄存器变量,则在每当进入函数或分程序时进行初始化。初始化符不一定限定为常量,它可以是任何表达式,甚至可以包含函数调用。实际上,自动变量的初始化部分就是赋值语句的缩写。
数组的初始化:
也是通过说明中初始化符来完成的,数组初始化符用“{}”括住,并用逗号分隔。
如果初始化符序列中的初始化符的个数比数组元素少时,那么对于没有得到初始化的数组元素在该数组为自动变量、外部变量、静态变量时都被初始化为0。