函数C语言中的static详细分析

c语言static  时间:2021-02-28  阅读:()

C语言中的stati c详细分析 标签语言cfi leserver编译器reference

2011-08-2212:0432786人阅读评论(34)收藏举报分类

C 4

版权声明本文为博主原创文章未经博主允许不得转载。g oog le了近三页的关于C语言中s tati c的内容发现可用的信息很少要么长篇大论不知所云要么在关键之处几个字略过对于想挖掘底层原理的初学者来说参考性不是很大。所以我这篇博文博采众家之长把互联网上的资料整合归类并亲手编写程序验证之。

C语言代码是以文件为单位来组织的在一个源程序的所有源文件中一个外部变量注意不是局部变量或者函数只能在一个源程序中定义一次如果有重复定义的话编译器就会报错。伴随着不同源文件变量和函数之间的相互引用以及相互独立的关系产生了exte rn和s tatic关键字。

下面详细分析一下s tati c关键字在编写程序时有的三大类用法

一 s tatic全局变量

我们知道一个进程在内存中的布局如图1所示

其中.text段保存进程所执行的程序二进制文件 .data段保存进程所有的已初始化的全局变量 .bss段保存进程未初始化的全局变量其他段中还有很多乱七八糟的段暂且不表 。在进程的整个生命周期中 .data段和.bss段内的数据时跟整个进程同生共死的也就是在进程结束之后这些数据才会寿终就寝。

当一个进程的全局变量被声明为static之后它的中文名叫静态全局变量。静态全局变量和其他的全局变量的存储地点并没有区别都是在.data段已初始化或者.bss段未初始化 内但是它只在定义它的源文件内有效其他源文件无法访问它。所以普通全局变量穿上static外衣后它就变成了新娘 已心有所属只能被定义它的源文件新郎中的变量或函数访问。

以下是一些示例程序fi le1 h如下

[cpp]view plaincopy

我们在fi le1 c中定义一个静态全局变量hello,供fi le1 c中的函数printStr访问

[cpp]view plaincopy

! ";

;fi le2c是我们的主程序所在文件 fi le2c中如果引用hel lo会编译出错

[cpp]view plaincopy

报错如下

[l iujx@server235static]$gcc-Wal l fi le2 cfi le1 c-o fi le2fi le2c: Infunction„main‟ :fi le2c:6:错误 „hel lo‟未声明(在此函数内第一次使用)fi le2c:6:错误 (即使在一个函数内多次出现每个未声明的标识符在其fi le2c:6:错误所在的函数内只报告一次。 )

如果我们将fi le2 c改为下面的形式

[cpp]view plaincopy

则会顺利编译连接。

运行程序后的结果如下

[l iujx@server235static]$gcc-Wal l fi le2 cfi le1 c-o fi le2

[l iujx@server235 static]$ /fi le2hel lo cobing!

上面的例子中 fi le1 c中的hel lo就是一个静态全局变量它可以被同一文件中的printStr调用但是不能被不同源文件中的fi le2 c调用。

二 s tatic局部变量

普通的局部变量在栈空间上分配这个局部变量所在的函数被多次调用时每次调用这个局部变量在栈上的位置都不一定相同。局部变量也可以在堆上动态分配但是记得使用完这个堆空间后要释放之。static局部变量中文名叫静态局部变量。它与普通的局部变量比起来有如下几个区别

1 位置静态局部变量被编译器放在全局存储区.data 注意不在.bss段内原因见3  所以它虽然是局部的但是在程序的整个生命周期中存在。

2访问权限静态局部变量只能被其作用域内的变量或函数访问。也就是说虽然它会在程序的整个生命周期中存在由于它是static的它不能被其他的函数和源文件访问。

3值静态局部变量如果没有被用户初始化则会被编译器自动赋值为0 以后每次调用静态局部变量的时候都用上次调用后的值。这个比较好理解每次函数调用静态局部变量的时候都修改它然后离开下次读的时候从全局存储区读出的静态局部变量就是上次修改后的值。

以下是一些示例程序fi le1 h的内容和上例中的相同 fi le1c的内容如下

[cpp]view plaincopy

为了便于比较我定义了两个变量普通局部变量norma l和静态局部变量stat它们都被赋予初值0fi le2c中调用fi le1 h

[cpp]view plaincopy

这个调用会报错 因为fi le2 c中引用了fi le1 c中的静态局部变量stat如下

[l iujx@server235static]$gcc-Wal l fi le2 cfi le1 c-o fi le2fi le2c: Infunction„main‟ :fi le2 c:9:错误 „stat‟未声明(在此函数内第一次使用)fi le2c:9:错误 (即使在一个函数内多次出现每个未声明的标识符在其fi le2c:9:错误所在的函数内只报告一次。 )

编译器说stat未声明这是因为它看不到fi le1 c中的stat下面注掉这一行

[cpp]view plaincopy

[l iujx@server235static]$gcc-Wal l fi le2 cfi le1 c-o fi le2

[l iujx@server235 static]$ /fi le2norm al=0----stat=0norm al=0----stat=1norm al=0----stat=2norm al=0----stat=3

运行如上所示。可以看出 函数每次被调用普通局部变量都是重新分配而静态局部变量保持上次调用的值不变。

需要注意的是由于static局部变量的这种特性使得含静态局部变量的函数变得不可重入 即每次调用可能会产生不同的结果。这在多线程编程时可能会成为一种隐患。需要多加注意。

三 s tatic函数

相信大家还记得C++面向对象编程中的private函数私有函数只有该类的成员变量或成员函数可以访问。在C语言中也有“private函数”它就是接下来要说的static函数完成面向对象编程中private函数的功能。

当你的程序中有很多个源文件的时候你肯定会让某个源文件只提供一些外界需要的接口其他的函数可能是为了实现这些接口而编写这些其他的函数你可能并不希望被外界非本源文件所看到这时候就可以用s tati c修饰这些“其他的函数”。

所以static函数的作用域是本源文件把它想象为面向对象中的private函数就可以了。

下面是一些示例fi le1 h如下

[cpp]view plaincopy

fi le1c如下

[cpp]view plaincopy

fi le2c中调用fi le1 h中声明的两个函数此处我们故意调用cal led():

[cpp]view plaincopy

编译时会报错

[l iujx@server235static]$gcc-Wal l fi le2 cfi le1 c-o fi le2fi le1 h:3:警告 „cal led‟使用过但从未定义

/tmp/ccyLuBZU o: In function`main' :fi le2 c:( text+0x12):undefined reference to`cal led'co l l ect2: l d返回1

因为引用了fi le1 h中的static函数所以fi le2 c中提示找不到这个函数:undefined reference to'cal led'

下面修改fi le2 c:

[cpp]view plaincopy

编译运行

[l iujx@server235static]$gcc-Wal l fi le2 cfi le1 c-o fi le2

[l iujx@server235 static]$ /fi le2returnVal=6s tatic函数可以很好地解决不同原文件中函数同名的问题 因为一个源文件对于其他源文件中的s tati c函数是不可见的。有疏漏的地方望各位多多指教~~

Megalayer美国独立服务器新用户首月优惠350元(30M优化不限流量)

Megalayer 商家在开始看到有提供香港服务器、香港站群服务器的时候有介绍过,后来就一直没有怎么关注。但是前几天有看到网友使用到他们家的美国独立服务器问其如何的,但是我没有使用过就不好评论,这不前几天也有介绍到Megalayer美国独立服务器。以及我们也有看到商家有提供美国站群服务器和美国大带宽服务器产品,可选30M不限制流量CN2优化线路,以及100M不限制流量国际带宽线路。新年元旦后,Me...

欧路云(22元/月),美国CERA弹性云服务器!香港弹性云服务器15元/月起;加拿大高防vps仅23元/月起

欧路云怎么样?欧路云主要运行弹性云服务器,可自由定制配置,可选加拿大的480G超高防系列,也可以选择美国(200G高防)系列,也有速度直逼内地的香港CN2系列。所有配置都可以在下单的时候自行根据项目 需求来定制自由升级降级 (降级按天数配置费用 退款回预存款)。2021年7月14日美国 CERA 弹性云服务器 上新 联通CUVIP 线路!8折特惠中!点击进入:欧路云官方网站地址付款方式:PayPa...

iWebFusion:独立服务器月付57美元起/5个机房可选,10Gbps服务器月付149美元起

iWebFusion(iWFHosting)在部落分享过很多次了,这是成立于2001年的老牌国外主机商H4Y旗下站点,提供的产品包括虚拟主机、VPS和独立服务器租用等等,其中VPS主机基于KVM架构,数据中心可选美国洛杉矶、北卡、本德、蒙蒂塞洛等。商家独立服务器可选5个不同机房,最低每月57美元起,而大流量10Gbps带宽服务器也仅149美元起。首先我们分享几款常规服务器配置信息,以下机器可选择5...

c语言static为你推荐
ptrC++~*ptr是什么?iphone5解锁苹果5忘了锁屏密码怎么解锁密码吴晓波频道买粉罗辑思维,晓松奇谈,鸿观,吴晓波频道,财经郎眼哪个更有深度伪静态什么是伪静态伪静态有何作用免费免费建站电脑上有真正免费的网站吗??安全漏洞什么是安全漏洞攻击??什么是云平台云平台和云计算的区别是什么?微信电话本怎么用微信电话本如何使用?微信怎么看聊天记录怎样才能调取微信聊天记录网站排名靠前怎样才能做好一个网站?让网站排名靠前?新手求解
购买域名 .cn域名注册 便宜vps 贝锐花生壳域名 payoneer 好看的桌面背景图片 国外免费全能空间 cn3 shopex主机 如何建立邮箱 免费mysql数据库 万网主机管理 英雄联盟台服官网 申请免费空间 alexa世界排名 标准机柜 apachetomcat e-mail 超低价 winscpiphone 更多