C/C++学习笔记23:全局变量与局部变量

来源:互联网 发布:网络语cp 编辑:程序博客网 时间:2024/06/05 03:45

关于全局变量与局部变量的基础性的东西是C中的一个重点,本节将重点讨论局部变量、全局变量、static局部变量、static全局变量等多种变量类型及其使用。

1:何为局部变量与全局变量?
局部变量:在一个函数内部定义的变量是内部变量,它只在本函数范围内有效,也就是说只在本函数内才能使用。

说明:main函数中的变量也只能在main函数中有效,main函数不能使用其他函数中定义的变量。

另外:在一个函数内部,可以在复合语句中定义变量,这些变量只在复合语句中有效。如:

void main(){int a,b;...{int c; //c也只在此语句块中有效
c=a+b;}...}

全局变量:程序的编译单位是源程序文件,一个源文件可以包含一个或若干个函数,在函数内定义的变量是局部变量,而在函数外定义的变量称之为外部变量,外部变量是全局变量。全局变量可以为本文件中其他函数所用,有效范围从定义变量的位置开始到本源文件结束。

要求:在C程序设计中,有个不成文的规定:要将全局变量名的第一个字母大写表示


2:全局变量与局部变量是否可以重名?

可以,如果在同一个源文件中,外部变量与局部变量同名,则在局部变量的作用范围内,外部变量被“屏蔽”,即它不起作用。


3:浅谈变量的存储类别

关于变量值的存储,在说栈区与堆区区别的时候也有提到:

http://blog.csdn.net/gzbaishabi/article/details/38584747

当时就提到了不同的变量值存放在不同的区域,里面的全局变量区也可以称之为静态区,而栈区与堆区都是动态分配的,所以也叫做动态区。因此在变量值存储的角度来说又可以分为:静态存储方式动态存储方式。具体的又分为:

(1)自动的(auto)

(2)静态的(static)

(3)寄存器的(register)

4)外部的(extern)

存储分类:

静态存储区:全部的全局变量

动态存储区:

(1)函数的形式参数

(2)自动变量(未加static声明的局部变量)

(3)函数调用时的现场保护和返回地址



4:深入浅出变量类型


局部变量:

(1)auto变量

函数中的局部变量,如果不专门声明为static存储类别,都是动态地分配存储空间,数据存储在动态存储区中。

如:函数中的形参和在函数中定义的变量

关键字“auto”可以省略,auto不写则隐含的确定为“自从存储类别”,他属于动态存储方式。程序中大多属于此类型。

(2)static声明局部变量

有时候希望函数中的局部变量的值在函数调用结束后不消失而保留原值,即其占用的存储单元不释放,在下一次该函数调用时,该变量已有值,就是上一次 函数调用结束时的值。这时就应该指定该局部变量为“静态局部变量”,用static声明。

如下图例子所示:




问题一:普通局部变量和static局部变量有什么区别?

(1)静态局部变量属于静态存储类别,在静态存储区内分配内存存储单元。在程序整个运行期间都不释放。而自动变量属于动态存储类别,占动态存储空间而不占静态存储空间。

(2)static局部变量只初始化一次,下一次依据上一次的结果值。


全局变量:

问题二:如何引用一个已经定义了的全局变量?(一个文件的程序)

问题延伸:如果外部变量不在文件开头定义,其有效的作用范围只限于定义处到文件结束。如果在定义前的函数想引用该外部变量。如何引用?

分析:使用关键字extern对该变量做“外部变量声明”,表示该变量是一个已经定义的外部变量。有了此声明,可以从“声明”处起,合法的使用该外部变量。

e.g.1:

#include <stdio.h>void main(){int max(int,int );extern A,B;   //外部声明变量printf("%d\n",max(A,B));}int A=13,B=-18;int max(int x,int y){int z;  //定义外部变量z=x>y?x:y;return z;}


问题三:上述介绍中,是在一个文件中可以用extern来声明一个全局变量,那如果是在多个文件中都要使用该变量,如何解决?
分析:比如说两个文件中都使用了一个外部变量Num,不能分别在两个文件中各自定义一个外部变量,否则在警醒程序的连接时会出现“重复定义”的错误。

正确的做法是:在任何一个文件中定义外部变量Num,在另一个文件中用extern对Num做“外部变量声明”。

/****file1.c****/int A;void main(){.......}/***file2.c****/extern A;int power(int n){....}

总结:extern既可以用来扩展外部变量在本文件中的作用域,又可以使外部变量的作用域从一个文件扩展到另一个文件。

问题四:系统如何处理extern带来的作用域扩展?

分析:在编译时遇到extern时,先在本文件中找到外部变量的定义,如果找到,就在本文件中扩展作用域;如果找不到,就在连接时从其他文件中找到外部变量的定义。如果从其他文件中找到,就将作用域扩展到本文件;如果找不到就按出错处理。


问题五:程序设计中希望某些外部变量只限于本文件引用,而不能被其他文件引用。如何处理?

static变量

针对这个问题:可以用static变量来声明。

/****file1.c****/static int A;void main(){...}/*****file2*****/extern int A;void fun(int n){...A=A*n;...}

在file1.c中定义了一个static的全局变量,因此只适用于本文件,虽然file2.c文件中用了extern int A,但file2.c中无法适用file1.c中的全局变量。


问题六:static全局变量和普通全局变量有什么区别?

static全部变量只初始化一次,防止被其他文件使用。

问题七:全局变量可以不可以被多个.c文件包含的头文件中?为什么?

可以,可以在不同的文件用声明static全局变量,但是只能在某一个文件中初始化一次。否则会出错。


寄存器变量

一般情况下,变量(包括静态存储方式和动态存储方式)的值都存放在内存中。当程序中用到哪一个变量的值时,由控制器发出指令将内存中该变量的值送到运算器。经过运算器进行运算,如果需要存数,再从运算器 将数据送到内存存放。

如果有一些变量使用频繁,则为存取变量的值花费不少时间。为提高执行效率,C语言允许将局部变量的值存放在CPU中的寄存器中,需要时直接从寄存器去处运算,不必再到内存中存取。这样的变量用register声明。

问题:哪些变量可以作为寄存器变量?
(1)只有局部自动变量形式参数可以作为寄存器变量,其他的不行。在调用一个函数时占用一些寄存器变量以存放寄存器变量的值,函数调用结束释放。

(2)一个计算机系统中的寄存器数目有限,不能同时定义任意多个寄存器变量,不同的系统允许的寄存器变量个数也不同。

(3)局部静态变量不能定义为寄存器变量。


0 0
原创粉丝点击