zoukankan      html  css  js  c++  java
  • C语言作用域、链接属性和存储类型

    C/C++中作用域详解

    作用域

    编译器可以确认的4种作用域-代码块作用域、文件作用域、函数作用域和原型作用域,一般来说,标识符(包括变量名和函数名)声明的位置决定它的作用域。

    (1)代码块作用域

    一对花括号成为一个代码块,任何在代码块开始位置声明的标识符(不包括代码块的函数名)具有代码块作用域。

    代码块处于嵌套状态时,声明于内层代码块的标识符的作用域到达该代码块的尾部(包括花括号)便终止。注意:如果内层代码块的某个变量与外层相同,内层会将外层的变量隐藏,即内层代码块无法访问到外层标识符。

    (2)文件作用域

    任何在所有代码块之外声明的标识符都具有文件作用域,表示从声明之处到源文件结尾都是可以访问的,包括定义的函数名,函数名本身不属于代码块。

    (3)原型作用域

    原型作用域只适用于函数原型中的参数名。

    (4)函数作用域

    这种作用域只适用于语句标签,如goto语句。

    链接属性

    标识符的链接属性决定处理在不同文件中出现的标识符,一共分三种-external(外部),internal(内部)和none(无)。

    internal属性的标识符在同一个源文件内所有的声明都指向同一个实体,但不同文件的多个声明则表示不同的实体,比如static声明的变量和函数的链接属性。

    external属性的标识符不论声明多少次,位于几个源文件都表示同一个实体,比如extern声明的变量和函数,或者缺省情况下的全局变量。

    none属性的标识符,比如代码块中声明的局部变量。

    extern和static用于在声明中修改标识符的链接属性:比如为external属性的标识符前加static则会变成internal,注意:非外部链接的变量前加static,将不会改变链接属性,比如局部变量前加static会变成静态局部变量;extern关键字表示可以访问在其他位置(全局变量)定义的这个实体,但需要注意如果一个变量声明于代码内部,extern关键字将使它引用全局变量而不是局部变量。

    存储类型

    变量的存储类型是指存储变量值的内存类型,变量的存储类型决定变量何时创建,何时销毁以及它的值将保持多久。普通内存、运行时堆栈、硬件寄存器可以存储变量。

    凡是在代码块之外声明的变量总是存储在静态内存中,也就是不属于堆栈的内存,这类变量称为静态变量,静态变量在程序运行之前创建,程序运行期间都会存在,程序结束则销毁,他始终保持原有值,除非被赋予其他值。

    代码块内部声明的变量的缺省存储类型是自动变量,存储于堆栈中,每次调用时执行到声明变量的代码块时才创建,离开时便销毁。反复调用时,他们的值并不是上次执行的值。变量前加static会变成静态变量,但不会改变其作用域。函数的形参不能声明为静态,因为实参总是在堆栈中传递给函数。

    register寄存器变量,表示变量存储在寄存器中而不是内存中,用于自动变量的声明,这并不能保证将变置在寄存器中,甚至也不能保证提高访问速度。这只是对编译器的一个暗示。

    使用register变量是有限制的:(1) 不可能得到或计算register 变量的地址; (2) register变量只能在一个块中声明(不可能有全局的或静态的register变量)。然而可以在一个函数中(即在参数表中)使用register变量作为一个形式参数。

     自动变量和静态变量的初始化也有差异,静态变量只在程序开始时执行一次,若不显式的初始化,将被初始化为0,每次调用时自动变量的存储位置可能不同,因此没有显式初始化的值。

    变量的作用域

    静态变量主要是全局变量、静态全局变量、静态局部变量,自动变量分为局部变量,寄存器变量

    (1) 全局变量:

       全局变量是在所有函数体的外部定义的,程序的所在部分(甚至其它文件中的代码)都可以使用。全局变量不受作用域的影响(也就是说,全局变量的生命期一直到程序的结束)。

    (2) 局部变量:

        局部变量出现在一个作用域内,它们是局限于一个函数的。

    (3) 寄存器变量

       寄存器变量是一种局部变量。关键字register告诉编译器“尽可能快地访问这个变量”。加快访问速度取决于现实,但是,正如名字所暗示的那样,这经常是通过在寄存器中放置变量来做到的。这并不能保证将变置在寄存器中,甚至也不能保证提高访问速度。这只是对编译器的一个暗示。

    (4) 静态变量

       关键字static有一些独特的意义。通常,函数中定义局部变量在函数中作用域结束时消失。当再次调用这个函数时,会重新创建变量的存储空间,其值会被重新初始化。如果想使局部变量的值在程序的整个生命期里仍然存在,我们可以定义函数的局部变量为static(静态的),并给它一个初始化。初始化只在函数第一次调用时执行,函数调用之间变量的值保持不变,这种方式,函数可以“记住”函数调用之间的一些信息片断。这也就是所谓的静态局部变量,具有局部作用域,它只被初始化一次,自从第一次被初始化直到程序运行结束都一直存在,它和全局变量的区别在于全局变量对所有的函数都是可见的,而静态局部变量只在定义自己的函数体内始终可见。

       我们可能奇怪为什么不使用全局变量。static局部变量的优点是在函数范围之外它是不可用的,所以它不可能被轻易改变。这会使错误局部化。

       此外同样存在静态全局变量,具有全局作用域,它与全局变量的区别在于如果程序包含多个文件的话,它作用于定义它的文件里,不能作用到其它文件里,即被static关键字修饰过的变量具有文件作用域。这样即使两个不同的源文件都定义了相同名字的静态全局变量,它们也是不同的变量。

      从分配内存空间看:全局变量,静态局部变量,静态全局变量都在静态存储区分配空间,而局部变量在栈里分配空间。

    注意:在程序中不要使用过多的全局变量,尽量用静态局部变量进行替代。

  • 相关阅读:
    关于Weblogic的知识点
    关于Linux常用命令的使用
    VirtualBox虚拟机下Linux CentOS6.9安装增强功能
    并发与高并发(一)-缓存一致性
    麦田厦门小区信息数据爬取
    CRM 增加信息不进行readonly,自定义user
    CRM form按field自定义,多选readonly
    CRM readonly、Form and field validation——第27天
    CRM action 多选框删除——第25,26天
    CRM删除数据——24天
  • 原文地址:https://www.cnblogs.com/qinguoyi/p/10105695.html
Copyright © 2011-2022 走看看