朗朗空间

我知道并不是 所有鸟儿都飞翔

  C++博客 :: 首页 :: 联系 :: 聚合  :: 管理
  16 Posts :: 0 Stories :: 6 Comments :: 0 Trackbacks

常用链接

留言簿(1)

我参与的团队

搜索

  •  

最新随笔

最新评论

阅读排行榜

评论排行榜

2.链接
一个C变量具有下列链接之一:
外部链接 (external linkage)
内部链接 (internal linkage)
空链接 (no linkage)
具有代码块作用域或者函数原型作用域的变量具有空链接,意味着它们是由其定义所在的代码块或函数原型所私有的。
具有文件作用域的变量可能有内部或者外部链接。
一个具有外部链接的变量可以在一个多文件程序的任何地方使用。
一个具有内部链接的变量可以在一个文件的任何地方使用。
那怎样知道一个文件作用域变量具有内部链接还是外部链接?
你可以看看在外部定义中是否使用了存储类说明符static:

int giants = 5;//文件作用域,外部链接
static int dodgers = 3;//文件作用域,内部链接
int main ()
{
    ……
}

和该文件属于同一程序的其他文件可以使用变量giants。
变量dodgers是该文件私有的,但是可以被该文件中的任一函数使用。

2.存储时期
一个C变量有两种存储时期之一:
静态存储时期(static storage duration)和自动存储时期(automatic storage duration)。
如果一个变量具有静态存储时期,它在程序执行期间将一直存在。
具有文件作用域的变量具有静态存储时期。
注意对于具有文件作用域的变量,关键字static表示链接类型,并非存储时期。
因为所有的文件作用域变量,无论它具有内部链接,还是具有外部链接,都具有静态存储时期。

具有代码块作用域的变量一般情况下具有自动存储时期。
当程序进入定义这些变量的代码块时,将为这些变量分配内存。
当推出这个代码块时,内存将被释放。
这样,在一个函数调用结束后,它的变量所占用的内存空间可以用来存储下一个被调用函数的变量。

到现在我们所使用的局部变量都属于自动类型。

void bore (int number)
{
    
int index;
    
for (index = 0; index < number; index++)
    
{
        
puts ("They don't make them the way they used to.\n");
        
return 0;
    
}
}

总论:c使用作用域、链接和存储时期来定义5中存储类。
自动,寄存器、具有代码块作用域的静态、具有外部链接的静态、具有内部链接的静态
1.自动变量
自动变量具有自动存储时期、代码块作用域和空链接。
默认情况下,在代码块或函数的头部定义的任意变量都属于自动存储类。
你可以显示的使用关键字auto来表明一个变量为自动变量,但我们一般不写。

int main (void)
{
    
auto int plox;
}
 
int loop (int n)
{
    
int m// m的作用域
    
scanf ("%d", &m);
    
{
        
int i; // m和i的作用域
        
for (i=m; i < n; i++)
        
{
            
puts ("i is local to a sub-block\n");
        
}
    
}
    
    
return m// m的作用域, i已经消失
}

如果在内层代码块定义了一个具有和外层代码块便来那个同一名字的变量,将会怎样?
(最好不要在你的代码中这样做)
这时内层代码块将使用在内层代码块中这个新定义的变量。
我们称之为内层定义覆盖(hide)了外部定义,只有当运行离开内层代码块是,外部变量才会重新恢复使用。

#include <stdio.h>
int main (void)
{
    
int x = 30;
    
printf ("x in outer block: %d\n", x);
    
{
        
int x = 77;
        
printf ("x in inner block: %d\n", x);
    
}
}

注意:
c99中规定,语句若为循环或者if语句的一部分,即使没有使用{},也认为是一个代码块。

#include <stdio.h>
int main (void)
{
    
int n = 10;
    
printf ("Initially, n = %d\n", n);
    
    
for (int n = 1; n < 3; n++)
        
printf ("loop : n = %d\n", n);
    
    
printf ("Initially, n = %d\n", n);
    
    
return 0;
}

注意:
除非您显式地初始化自动变量,否则它不会被自动初始化。

int main (void)
{
    
int repid;
    
int tents = 5;
}

repid的初值则是先前占用分配给它的空间的任意值。不要指望这个值是0。

2.寄存器变量
通常,变量存储在计算机内存中。如果幸运,寄存器变量可以被存储在CPU的寄存器中,这样速度会更快。
在其它许多方面,它和自动变量是一样的。
通过使用存储类型说明符register可以声明寄存器变量。

int main (void)
{
    
register int quick;
}

我们说如果幸运是因为声明一个寄存器类变量仅仅是一个请求,而不是一条直接命令。
因为CPU寄存器往往很少,编译器必须在可用寄存器的个数和可用高速内存的数量之间做权衡。
这种情况下,变量成为一个普通的自动变量。
但是,你不能对它使用地址运算符。
可以把一个形式参量请求为寄存器变量。

void macho (register int n)

3.具有代码块作用域的静态变量
静态变量像是一个不可变的变量。
但实际上,静态指变量的的位置固定不动。
具有文件作用域的变量自动的具有静态存储时期。
也可以创建具有代码块作用域,兼具有静态存储的局部变量。
这些变量和自动变量具有相同的作用域,当包含这些变量的函数完成工作时,它们并不消失。
从一次函数调用到下一次调用,计算机都记录着他们的值。
我们可以使用存储类说明符static在代码块内声明这些变量。

#include <stdio.h>
void trystat (void);
int main (void)
{
    
int count;
 
    
for (count = 1; count <= 3; count++)
    
{
        
printf ("Here comes iteration %d:\n", count);
        
trystat ();
    
}
    
    
return 0;
}
 
void trystat (void)
{
    
int fade = 1;
    
static int stay = 1;
    
    
printf ("fade = %d and stay = %d\n", fade++, stay++);
}

注意:
对函数参数不能使用static。
4.具有外部链接的静态变量
具有外部链接的静态变量具有文件作用域、外部链接和静态存储时期。
这一类型的变量成为外部变量 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)
{
}

注意:
不同于自动变量,如果您不对外部变量进行初始化,他们将自动被赋初值0。
这一原则也适用于外部定义的数组。

5.具有内部静态链接的静态变量
通过使用存储类说明符(注意不是静态变量声明符)static在所有函数的外部进行定义,前面已经说过该变量为整个文件私有

,这里不再讨论。

int traveler = 1; //外部链接
static int stayhome = 1; //内部链接
posted on 2008-05-06 20:18 聂元朗 阅读(418) 评论(0)  编辑 收藏 引用 所属分类: C语言学习笔记

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理