C语言变量的属性

来源:互联网 发布:房屋中介管理系统源码 编辑:程序博客网 时间:2024/05/18 02:55

          变量的属性有五种:

        (1)名字(必须显示说明)

        (2)类型 (必须显示说明)

        (3)存储类别 (缺省方式或显示说明(使用:auto、register、static、extren))

        (4)作用域  (由存储类别决定)

        (5)生存期  (由存储类别决定)

          前两种不必解释了,顾名思义。下面详细区分后三种概念:

  • 变量的存储类别

          定义:指系统对变量存储方式的规定。

          分类:由存储方式的不同分为两类:

          (1)静态存储方式:指在程序运行期间,系统对变量固定地分配存储空间。即一旦分配,不在变化,直到整个程序运行结束。

          (2)动态存储方式:指在程序运行期间,系统对变量动态地分配存储空间。即程序运行期间,可根据程序需求,动态分配。

          存储类别既说明了变量的存储单元,又说明了变量的生存的时间和作用域。

          具体包含四种:

          在讨论一下四种限定符之前,先注明一个事实:在某一个程序文件中定义的全局变量和函数均默认是外部的!即跨文件的,但为什么使用还要加extern?这个稍后再讲。

          (1)自动变量auto:指不加说明的局部变量。变量生存期结束由系统自动释放其存储空间,故名自动。

          (2)寄存器变量register:为提高程序执行效率,允许将局部变量的值存放于寄存器(而不必存在内存)中,但一般不提倡这种做法。

          (3)static变量:可作用于局部变量和全局变量,故可分为:局部静态和全局静态。静态(static)说的是:生存期;而局部or全局说的是:作用域(However,此时应注意:由于全局变量作用域本来就默认为整个程序中,即可垮文件使用(公有);可一旦加上static修饰,则隐藏了变量或函数名字,使之成为本文件(模块)私有)。

          (4)以extern声明的变量:指全局变量,若其要在其他文件中使用,需加以声明,方法-->使用前用extern作外部声明即可(通常放于文件开头,并且对于函数而言,通常省略关键字extern)。

总的来说:变量的存储类别+定义变量的位置 =》变量的作用域和生存期

  • 变量的作用域
        定义:作用,即起作用,有效的意思;域即范围。连起来就是指:变量的有效范围,它从空间角度体现变量的特性。
       分类(六种):
         (1)全局变量作用域(包括全局变量和全局静态变量两种);
         (2)局部变量作用域;
         (3)语句作用域;
         (4)类作用域;
         (5)命名空间作用域;
         (6)文件作用域。
  • 变量的生存期
        定义:指从变量创建至删除所经历的时间段,它从时间角度体现变量的特性。 
       分类(三种):
         (1)动态生存期:指存放在“堆区”中的数据。创建、删除均由程序员自己完成。
         (2)局部生存期:指存放在“栈区”中的数据。
         (3)静态生存期:指存放在“(全局)数据区”中的数据。程序一运行,它们就开始存在;程序一结束,它们就由系统自动释放。

ps:现在来回答:为什么使用还要加extern?
问题完整描述:既然全局变量(不同于静态全局变量)默认是动态的,即作用域整个工程,那么为什么在另一个文件中还要加extern声明,才能使用它?
答:
        先明确下extern的定义:extern可以置于变量或函数前,以表示变量或函数的定义在别的文件中,提示编译器遇到次变量或函数时应在其他模块中寻找定义。所以extern只是起到一个提示作用,它与编译器协同工作。
        从编译器的角度:现代编译器一般采用按文件编译的方式,即编译的时候,各个文件是互相透明的(即不可见)。
         这就告诉我们:虽然全局变量默认为动态,即作用域可以跨文件到整个工程,但是现代编译器在编译的时候限制了这个缺省条件。而是在链接阶段,各个文件才“合为一体”,故文件中定义的全局变量的作用域扩展至整个工程是在链接之后才完成的。同时,又由于在链接阶段,若在不同文件中有相同名字的全局变量,则会出现重定义的错误,即一个程序的各个文件中定义的全局变量不能相同。所以重新定义变量不能解决问题,故只能采取:在一个文件中定义的全局变量,若其他文件中有需要,则用extern声明即可,以提示编译器,此变量的定义要去程序的其他文件中去找。
          因为编译器的“目光”并不够长远,它没有意识到,某个变量标识符虽然不是本文件中定义的,但是可能在其他文件中有定义,所以需要提示作用,extern由此而来,可算是一种约定。
0 0