博客
关于我
作用域、链接属性和存储类型
阅读量:416 次
发布时间:2019-03-06

本文共 1686 字,大约阅读时间需要 5 分钟。

重新认识C语言中的作用域、链接属性与存储类型

最近在研读《程序员的自我修养——链接、装载与库》时,脑海中不由自主地浮现出学习C语言时的那些摸索之路。尤其是当初对externstatic等关键字的理解,至今仍让人感到不自信。因此,我重新翻开了《C和指针》中关于作用域、链接属性和存储类型的相关内容,并结合自己的理解,整理出一篇技术博客。

一、作用域

作用域是程序中标识符可以被访问的区域。它的大小和范围,直接关系到代码的可维护性和调试难度。在编译原理中,编译器会在语义分析阶段检查变量的作用域是否符合规则。

代码块作用域

代码块作用域是最常见的作用域类型。任何在花括号{ }之间的代码都属于一个代码块。代码块内的标识符可以在整个代码块内访问,但需要注意的是,若在代码块内再次声明相同名称的变量,则外层声明的变量会被隐藏。

例如:

int a;  // 文件作用域{    int b;   // 代码块作用域    a = 10;  // 隐藏了外层的a}

文件作用域

文件作用域是指标识符在整个源文件范围内都可以访问的作用域。例如,int g;int func(int x);都具有文件作用域。这也是我们在编写代码时需要将函数声明放在源文件开头的原因。

原型作用域

原型作用域仅适用于函数原型中的参数名。例如,在int func(int x);中,x的作用域仅限于函数原型本身。

函数作用域

函数作用域主要用于语句标签(用于goto语句),在实际编程中较少使用。

总的来说,代码块作用域和文件作用域是最值得关注的两种作用域类型。

二、链接属性

链接属性决定了不同源文件中相同标识符的处理方式。它与作用域密切相关,但两者性质有所不同。

external

具有外部链接属性的标识符在所有源文件中都指同一个实体。缺省情况下,文件作用域的变量和函数具有external链接属性。

internal

具有内部链接属性的标识符在同一源文件内的所有声明都指同一个实体,但在不同源文件中则视为不同的实体。

none

没有链接属性的标识符被视为独立实体,通常用于不希望标识符在其他文件中被引用。

extern关键字

extern关键字用于为标识符指定external链接属性。它对文件作用域的标识符是可选的,但对代码块作用域的标识符则强制设置为external。

static关键字

static关键字用于将外部链接属性的标识符改为内部链接属性。需要注意的是,static只对缺省链接属性为external的声明有效。

三、存储类型

存储类型决定了变量的内存分配方式和存储位置。

静态内存

静态变量在程序运行前就已经分配好内存,存储在.data段或.bss段中。静态变量在整个程序执行过程中始终存在,除非程序结束。

运行时堆栈

缺省情况下,代码块内的变量存储在运行时堆栈中,称为自动变量。若在声明时使用static关键字,则变量将被存储在静态内存中。

寄存器

寄存器变量提示编译器将变量存储在硬件寄存器中。需要注意的是,register关键字的使用更多是编译器的优化提示,实际存储位置取决于编译器的选择。

四、初始化

静态变量在编译时已经初始化为0,不需要额外开销。自动变量则需要在运行时进行初始化,编译器会在代码块开始处插入赋值语句。

五、static和extern的辨别

staticextern在不同的上下文中具有不同的含义:

1. 对于文件作用域的标识符

  • static:将外部链接属性改为内部链接属性。
  • extern:可选项,用于明确标识符的链接属性。

2. 对于代码块作用域的标识符

  • static:将变量的存储类型从自动变为静态,但链接属性仍为none。
  • extern:将变量的链接属性从none改为external。

结语

通过对作用域、链接属性和存储类型的深入理解,我们可以更好地管理代码的私有化和信息的透明化。这不仅有助于提高代码的可维护性,也能为程序的性能优化提供重要依据。在实际编程中,合理使用staticextern关键字,可以让我们的代码更高效、更易于管理。

转载地址:http://derkz.baihongyu.com/

你可能感兴趣的文章
Openlayers实战:判断共享单车是否在电子围栏内
查看>>
Openlayers实战:绘制图形,导出geojson文件
查看>>
Openlayers实战:绘制图形,导出KML文件
查看>>
Openlayers实战:绘制多边形,导出CSV文件
查看>>
Openlayers实战:输入WKT数据,输出GML、Polyline、GeoJSON格式数据
查看>>
Openlayers高级交互(10/20):绘制矩形,截取对应部分的地图并保存
查看>>
Openlayers高级交互(11/20):显示带箭头的线段轨迹,箭头居中
查看>>
Openlayers高级交互(14/20):汽车移动轨迹动画(开始、暂停、结束)
查看>>
Openlayers高级交互(15/20):显示海量多边形,10ms加载完成
查看>>
Openlayers高级交互(16/20):两个多边形的交集、差集、并集处理
查看>>
Openlayers高级交互(17/20):通过坐标显示多边形,计算出最大幅宽
查看>>
Openlayers高级交互(19/20): 地图上点击某处,列表中显示对应位置
查看>>
Openlayers高级交互(2/20):清除所有图层的有效方法
查看>>
Openlayers高级交互(3/20):动态添加 layer 到 layerGroup,并动态删除
查看>>
Openlayers高级交互(6/20):绘制某点,判断它是否在一个电子围栏内
查看>>
Openlayers高级交互(8/20):选取feature,平移feature
查看>>
Openlayers:DMS-DD坐标形式互相转换
查看>>
openlayers:圆孔相机根据卫星经度、纬度、高度、半径比例推算绘制地面的拍摄的区域
查看>>
OpenLDAP(2.4.3x)服务器搭建及配置说明
查看>>
OpenLDAP编译安装及配置
查看>>