概述
具有外部链接的静态变量具有文件作用域、外部链接和静态存储时期。这一类型有时被称为外部存储类 (external storage class),这一类型的变量被称为外部变童(external variable)。把变量的定义声明放在所有函 数之外,即创建了一个外部变置。为了使程序更加清晰,可以在使用外部变童的函数中通过使用extern关键 字来再次声明它。如果变童是在别的文件中定义的,使用extern来声明该变童就是必须的。应该像这样声明:
Errupt的两次声明是个链接的例子,因为它们都指向同一变量。外部变量具有外部链接,稍后我们将 再提到这一点。请注意不必在double Up的可选声明中指明数组大小。第一次声明已提供了这一信息。因为外部变量 具有文件作用域,它们从被声明处到文件结尾都是可见的,所以main ()中的一组extern声明完全可以省 略掉。而它们出现在那里,作用只不过是表明main ()函数使用这些变童。int Errupt: /*外部定义的变*: */
double Up[100]:/*外部定义的数组 */
extern char Coal;/*必须的声明因为Coal在其他文件中定义*/
void next (void):
int main (void)
{extern int Errupt;/*可选的声明*/
extern double Up[];/*可选的声明*/
}
void next (void)
{
}
如果函数中的声明漏掉了 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<stdio.h>
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 upin");
return 0;
}
void critic(void)
{
/*这里省略了可选的二次声明*/
printf("No luck ,chummy.Try again.n");
scanf("%d",&units);
}
注意函数critic ()是怎样读取units的第二个值的;当main ()结束while循环时,也知道了新值。 因此,两个函数main ()和critic ()都用标识符units来访问同一个变量。在C的术语中,称units具有 文件作用域、外部链接以及静态存储时期。下面是-•个输出示例:
How many pounds to a firkin of butter?
U
No luck, chummy. Try again.
56
You must have looked it up!
通过在所有函数定义的外面(外部)定义变量units,它成为一个外部变量。要使units对文件中随后 的全部函数都可用,只需像前面这样做即可。
来看一些细节。首先,units声明所在的位置使得它对后面的函数可用,而不需采取任何其他操作。这 样,critics ()就可以使用变量units。
与之类似,也不需要做任何事来允许main ()访问units。然而,main ()中确实有如下的声明:
extern int units;
在这个例子中,声明主要是使程序的可读性更好。存储类说明符extern告诉编译器在该函数中用到的 unte都是指同一个在函数外部(甚至在文件之外)定义的变量。再次,main ()和critic ()•都使用了外部 定义的units。
最后
以上就是悦耳吐司为你收集整理的C Primer Plus学习 三十七 具有外部链接的静态变置的全部内容,希望文章能够帮你解决C Primer Plus学习 三十七 具有外部链接的静态变置所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复