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关键字修饰过的变量具有文件作用域。这样即使两个不同的源文件都定义了相同名字的静态全局变量,它们也是不同的变量。
从分配内存空间看:全局变量,静态局部变量,静态全局变量都在静态存储区分配空间,而局部变量在栈里分配空间。
注意:在程序中不要使用过多的全局变量,尽量用静态局部变量进行替代。
C语言作用域、链接属性和存储类型的更多相关文章
- C语言中的作用域,链接属性和存储类型
作用域 当变量在程序的某个部分被声明的时候,他只有在程序的一定渔区才能被访问,编译器可以确认4种不同类型的作用域:文件作用域,函数作用域,代码块作用域和原型作用域 1.代码块作用域:位于一对花括号之间 ...
- C和C指针小记(六)-基本声明、指针声明、typedef 、常量、作用域、链接属性、存储类型、static
1.变量的声明 声明变量的基本形式: 说明符号(一个或者多个) 声明表达式列表 说明符 (specifier) 包含一些关键字,用于描述被声明的标识符的基本类型,它也可用户改变标识符的缺省存储类型和作 ...
- 关于extern和static关键字引出的一些关于作用域和链接属性和存储类型的问题
在进入正题前我们必须了解一些概念: 标识符:标识符不仅仅代表着变量的名字,main()函数的main也是一个标识符,这点很重要. 存储类型:即变量的存储位置及其生存周期:静态区:分为两块 .date ...
- C语言中的作用域、链接属性与存储属性
C语言中的作用域.链接属性与存储属性 一.作用域(scope) 代码块作用域 表示{}之间的区域,下例所示,a可以在不同的代码块里面定义. #include<stdio.h> int ma ...
- C和指针 3.9作用域、存储类型示例
; extern int b; static int c; int d( int e ) { ; register int b; ; extern int a; ... { int e; int a; ...
- 7、存储类 & 作用域 & 生命周期 & 链接属性
概念解析 存储类 存储类就是存储类型,也就是描述C语言变量在何种地方存储. 内存有多种管理方法:栈.堆.数据段.bss段..text段······一个变量的存储类属性就是描述这个变量存储在何种内存段中 ...
- C语言中变量和函数的作用域和链接属性
C语言中变量和函数的作用域和链接属性 作用域 代码块作用域: 代码块指的是使用"{}"包围起来的部分. 在代码块中定义的变量,代码块之外是不能访问的. 代码块嵌套之后的变量作用域, ...
- C++变量的存储类型
C++变量和函数包括两个属性:数据类型和数据的存储类型.存储类型是指数据在内存中存储的方式.变量的存储类型分为四种:自动类型(auto),寄存器类型(register).静态类型(static)外部类 ...
- C语言中标识符的作用域、命名空间、链接属性、生命周期、存储类型
Technorati 标签: C,标识符,作用域,命名空间,链接属性,生命周期,存储类型,scope,name space,linkage,storage durations,lifetime 无论学 ...
随机推荐
- Windows 虚拟机 VM
VMware是全球台式电脑及资料中心虚拟化解决方案的领导厂商.VMWare Workstation是该公司出品的“虚拟 PC”软件(即:大家常说的“虚拟机”),通过它可在一台电脑上同时运行更多的Mic ...
- C++——类的继承(派生)
类的继承就是子类可以拥有父类的成员变量和成员函数 //public 修饰的成员变量 方法 在类的内部 类的外部都能使用//protected: 修饰的成员变量方法,在类的内部使用 ,在继承的子类中可用 ...
- net.sf.jsqlparser.statement.select.PlainSelect.getGroupBy()Lnet/sf/jsqlparse
添加pom依赖 <dependency> <groupId>com.github.jsqlparser</groupId> <artifactId>js ...
- layui点击按钮自动刷新页面问题
问题 <button class="layui-btn layui-btn-primary" onclick="findData()">查询< ...
- Android_Gallery(画廊)
转:http://blog.csdn.net/tianjf0514/article/details/7521398 Gallery是画廊的意思,可以实现图片的浏览功能. 主要内容 Gallery控件的 ...
- win7下mysql5.5与mysql5.6同时安装
5.5己正常的情况下,用官方下载的安装包总是不成功,用的官方解压版5.6.44 1.复制my-default.ini到my.ini,只需要改端口就行了,设置base-dir/data-dir反而无法启 ...
- laravel装饰者模式例子
interface Decorator{ public function display(); } class XiaoFang implements Decorator { private $nam ...
- nodejs与websocket模拟简单的聊天室
nodejs与websocket模拟简单的聊天室 server.js const http = require('http') const fs = require('fs') var userip ...
- mint-ui loadmore 上拉加载的坑
<div style="height:100vh;overflow: scroll;"> <mt-loadmore :top-method="loadT ...
- python语句结构(控制语句与pass语句)
python语句结构(控制语句和pass语句) break-跳出循环:语句可以跳出for和while语句的循环体.如果你从for和while循环中终止,任何对应循环的else语块均终止 continu ...