C Primer Plus学习 三十七 具有外部链接的静态变置

        具有外部链接的静态变量具有文件作用域、外部链接和静态存储时期。这一类型有时被称为外部存储类 (external storage class),这一类型的变量被称为外部变童(external variable)。把变量的定义声明放在所有函 数之外,即创建了一个外部变置。为了使程序更加清晰,可以在使用外部变童的函数中通过使用extern关键 字来再次声明它。如果变童是在别的文件中定义的,使用extern来声明该变童就是必须的。应该像这样声明:

int Errupt:  /*外部定义的变*: */

double Up[100]:/*外部定义的数组 */

 extern char Coal;/*必须的声明因为Coal在其他文件中定义*/

void next (void):

 int main (void)

extern int Errupt;/*可选的声明*/

extern double Up[];/*可选的声明*/

void next (void)

{

       Errupt的两次声明是个链接的例子,因为它们都指向同一变量。外部变量具有外部链接,稍后我们将 再提到这一点。请注意不必在double Up的可选声明中指明数组大小。第一次声明已提供了这一信息。因为外部变量 具有文件作用域,它们从被声明处到文件结尾都是可见的,所以main ()中的一组extern声明完全可以省 略掉。而它们出现在那里,作用只不过是表明main ()函数使用这些变童。
       如果函数中的声明漏掉了 extern,就会建立一个独立的自动变量。也就是说,如果在main ()中用:
      extern int Errupt:
      替换:
      int Errupt:
      将使编译器创建一个名为Enupt的自动变量。它将是一个独立的局部变量,而不同于初始的Emipt。在程 序执行main ()时该局部变量会起作用;但在像next ()这种同一文件内的其他函数中,外部的Emipt将起作用。简言之,在程序执行代码块内语句时,代码块作用域的变量覆盖了具有文件作用域的同名变量。
       外部变量具有静态存储时期。因此,数组Up—直存在并保持其值,不管程序是否在执行main ()、 next ()还是其他函数。
        下列3个例子展示了外部变量和自动变量的4种可能组合。例1中有一个外部变量•• Hocus。它对main () 和magic ()都是可见的。

/* 例 1 */ 

int Hocus;

 int magic ():

 int main (void)

{

extern int Hocus; // 声明 Hocus 为外部变童

int magic ()
{

extern int Hocus; // 与 1:面的 Hocus 是同一变量

        例2中有一个外部变量Hocus,对两个函数都是可见的。这次,magic ()通过默认方式获知外部变量。

/* 例 2 */ int Hocus;

 int magic (); 

int main (void)

{
extern int Hocus; // 声明 Hocus 为外部变量
}
int magic ()
{

//未声明Hocus,但知道该变量

       在例3中,创建了 4个独立的变量。main ()中的Hocus默认为自动变量,而且是main ()的局部变 量。magic ()中的Hocus被显式地声明为自动变量,只对magic ()可见。外部变量Hocus对main ()或 magic ()不可见,但对文件中其他不单独拥有局部Hocus的函数都可见。最后,Pocus是一个外部变量, 对magic ()可见而对main ()不可见,因为Pocus的声明在main ()之后

/* 例 3 */ 

int Hocus; 

int magic ();

int main (void)

{
int Hocus; //声明Hocus,默认为自动变量
}
int Pocus; int magic ()
{

auto int Hocus; // 把局部变量 Hocus 显式地声明为自动变量

       这些例子说明了外部变量的作用域:从声明的位置开始到文件结尾为止。它们也说明了外部变量的生 存期。外部变量Hocus和Pocus存在的时间与程序运行时间…样,并且它们不局限于任一函数,在一个特 定函数返回时并不消失。

      外部变量初始化

      和自动变量样,外部变量可以被显式地初始化。不同于自动变量的是,如果您不对外部变量进行初 始化,它们将自动被赋初值0。这一原则也适用于外部定义的数组元素。不同于自动变量,只可以用常量 表达式来初始化文件作用域变量:

int x = 10: //可以.10是常量

int y = 3 + 20;//可以,-个常量表达式

size_t z = sizeof (int): //可以,-个常t表达式

int x2 = 2 * x: //不可以.x是一个变量

        (只要类型不是一个变长数组,sizeof表达式就被认为是常量表达式 )

       外部变量的使用

       我们来看一个包含有外部变量的简单例子。特别地,假设需要两个分别叫作niahi ()和critic ()的 函数来访问变量units可以如程序清单12.4所示,在这两个函数之外的幵始处声明变量units.

/* globalT.7 —使用屏i泰量*/

#include

int units=0;                          /* 一个外部变景 */

void critic(void);

int main(void)

{

extern int units;                 /* 可选的乂次卢明 */

printf("How many pounds to a firkin of butter?\n");

scanf("%d",&units);

while(units!=56)

{

critic();

}

printf("You must bave looked it upi\n");

return 0;

}

void critic(void)

{

/*这里省略了可选的二次声明*/

printf("No luck ,chummy.Try again.\n");

scanf("%d",&units);

}

下面是-•个输出示例:

How many pounds to a firkin of butter?

U

No luck, chummy. Try again.

56

You must have looked it up!

        注意函数critic ()是怎样读取units的第二个值的;当main ()结束while循环时,也知道了新值。 因此,两个函数main ()和critic ()都用标识符units来访问同一个变量。在C的术语中,称units具有 文件作用域、外部链接以及静态存储时期。
        通过在所有函数定义的外面(外部)定义变量units,它成为一个外部变量。要使units对文件中随后 的全部函数都可用,只需像前面这样做即可。
        来看一些细节。首先,units声明所在的位置使得它对后面的函数可用,而不需采取任何其他操作。这 样,critics ()就可以使用变量units。

        与之类似,也不需要做任何事来允许main ()访问units。然而,main ()中确实有如下的声明:

extern int units;

        在这个例子中,声明主要是使程序的可读性更好。存储类说明符extern告诉编译器在该函数中用到的 unte都是指同一个在函数外部(甚至在文件之外)定义的变量。再次,main ()和critic ()•都使用了外部 定义的units。

你可能感兴趣的:(C,Primer,Plus学习,c语言,编程)