函数c语言中的static关键字

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

网上的几个介绍 引用在这里stati c关键字是C, C++中都存在的关键字,它主要有三种使用方式,其中前两种在C/C++语言中使用,第三种只在C++中使用(C,C++中具体细微操作不尽相同,本文以C++为准) .

(1)局部静态变量

(2)外部静态变量/函数

(3)静态数据成员/成员函数

下面就这三种使用方式及注意事项分别说明

一、局部静态变量

在C/C++中,局部变量按照存储形式可分为三种auto, stati c, register

(<C语言程序设计(第二版)>谭浩强, 第174-175页)

与auto类型(普通)局部变量相 比, stati c局部变量有三点不同

1.存储空间分配不同auto类型分配在栈上,属于动态存储类别, 占动态存储区空间, 函数调用结束后自动释放,而stat ic分配在静态存储区 ,在程序整个运行期间都不释放.两者之间的作用域相同 ,但生存期不同.

2. stati c局部变量在所处模块在初次运行时进行初始化工作,且只操作一次

3.对于局部静态变量,如果不赋初值,编译期会自动赋初值0或空字符,而auto类型的初值是不确定的. (对于C++中的cla ss对象例外, class的对象实例如果不初始化,则会自动调用默认构造函数,不管是否是stati c类型)

特点: stati c局部变量的”记忆性”与生存期的 ”全局性”

所谓”记忆性”是指在两次函数调用时,在第二次调用进入时, 能保持第一次调用退出 时的值.

示例程序一

#include <iostream>using namespace std;void stati cLoca lVar()

{stati c int a = 0; //运行期时初始化一次,下次再调用 时,不进行初始化工作cout<<"a="<<a<<endl ;

++a;

}int main()

{s tat i cLoca lVar() ; //第一次调用,输出a=0s tat i cLoca lVar() ; //第二次调用,记忆了第一次退出时的值,输出a=1return 0;

}

应用:

利用”记忆性” , 记录函数调用的次数(示例程序一)

利用生存期 的”全局性” , 改善” return a pointer / reference to a local object”的问题. Local objec t的问题在于退出函数,生存期即结束, .利用static的作用,延长变量的生存期.

示例程序二:

// IP addre ss to strin g format

// Used in Ethernet Frame and IP Header analy sisconst char * IpToS tr(UINT32 IpAddr)

{stati c char strBu ff[16] ; // stati c局部变量,用于返回地址有效const unsig ned char *pChIP = (const unsigned char *)&IpAdd r;sprin tf(strBu ff, "%u.%u.%u.%u", pChIP [0], pChIP [1], pChIP [2], pChIP [3]) ;return strBuff;

}

注意事项:

1. “记忆性”,程序运行很重要的一点就是可重复性,而stat ic变量的”记忆性”破坏了这种可重复性,造成不同时刻至运行的结果可能不 同.

2. “生存期”全局性和唯一性.普通的local变量的存储空间分配在stack上, 因此每次调用函数时, 分配的空间都可能不一样,而stat ic具有全局唯一性的特点,每次调用时,都指向同一块内存,这就造成一个很重要的 问题----不可重入性! ! !

这样在多线程程序设计或递归程序设计中, 要特别注意这个问题.

(不可重入性的例子可以参见<effec tive C++ (2nd)>(影印版)第103-105页)

下面针对示例程序二,分析在多线程情况下的不安全性. (为方便描述,标上行号)

①const char * IpToS tr(UINT32 IpAddr)

②{

③ stati c char strBu ff[16] ; // stati c局部变量,用于返回地址有效

④ const unsig ned char *pChIP = (const unsigned char *)&IpAdd r;

⑤ sprin tf(strBu ff, "%u.%u.%u.%u", pChIP [0], pChIP [1], pChIP[2], pChIP [3]) ;

⑥ return strBuff;

⑦}

假设现在有两个线程A,B运行期间都需要调用 IpToS tr()函数,将32位的IP地址转换成点分1 0进制的字符串形式. 现A先获得执行机会,执行IpT oStr(),传入的参数是0x0B 090A0 A,顺序执行完应该返回的指针存储区 内容是: ” 10. 10.9. 11” ,现执行到⑥时, 失去执行权,调度到B线程执行, B线程传入的参数是0 xA8A8 A8C0, 执行至⑦,静态存储区 的内容是1 92. 168. 168. 168.当再调度到A执行时, 从⑥继续执行, 由于strBuff的全局唯一性,内容已经被B线程冲掉,此时返回的将是192 . 168. 168. 168字符串,不再是10. 10.9. 11字符串 .

二、外部静态变量函数

在C中static有了第二种含义用来表示不 能被其它文件访问的全局变量和函数。,但为了限制全局变量/函数的作用域,函数或变量前加static使得函数成为静态函数。但此处“static”的含义不是指存储方式而是指对函数的作用域仅局限于本文件(所以又称内部函数) 。注意此时,对于外部(全局)变量, 不论是否有stati c限制, 它的存储区域都是在静态存储区,生存期都是全局的. 此时的st atic只是起作用域限制作用, 限定作用域在本模块(文件)内部.

使用内部函数的好处是不同的人编写不同的函数时不用担心自己定义的函数是否会与其它文件中的 函数同名。

示例程序三:

//f i l e 1 .cppstati c int varA;int varB;

extern void funA()

{

„„

}stati c void funB()

{

„„

}

//f i l e2.cppextern int varB; //使用fil e1.cpp中定义的全局变量exter n int varA; //错误! varA是stati c类型,无法在其他文件中使用extern vod funA() ; //使用fil e1.cpp中定义的函数exter n void funB() ; //错误!无法使用f ile1. cpp文件中stat ic函数

三、静态数据成员成员函数(C++特有)

C++重用了这个关键字并赋予它与前面不同的第三种含义表示属于一个类而不是属于此类的任何特定对象的变量和函数.这是与普通成员函数的最大区别,也是其应用所在, 比如在对某一个类的对象进行计数时,计数生成多少个类的实例,就可以用到静态数据成员.在这里面,stati c既不是限定作用域的,也不是扩展生存期的作用,而是指示变量/函数在此类中的唯一性.这也是”属于一个类而不是属于此类的任何特定对象的变量和函数”的含义. 因为它是对整个类来说是唯一的, 因此不可能属于某一个实例对象的. (针对静态数据成员而言,成员函数不

管是否是s tatic,在内存中只有一个副本,普通成员函数调用时,需要传入t his指针, static成员函数调用时, 没有thi s指针. )

请看示例程序四(<effec tive c++ (2nd)>(影印版)第59页)class Enemy Targe t {publi c:

EnemyTarge t() { ++numTa rgets ; }

Enemy Targe t(const Enemy Targe t&) { ++numTa rgets ; }

~Enemy Targe t() { --numTa rgets ; }stati c size_t numbe rOfTargets () { return numTa rgets ; }bool destroy() ; // returns succe ss of attempt to destroy EnemyTarge t objectpriva te:stati c size_t numTargets ; // object count er

} ;

// class stati cs must be defined outside the class ;

// initialization is to 0 by defaultsize_t Enemy Targe t: :numTa rgets ;

在这个例子中,静态数据成员numT arget s就是用来计数产生的对象个数的 .

另外, 在设计类的多线程操作时, 由于POS IX库下的线程函数p threa d_cre ate()要求是全局的,普通成员函数无法直接做为线程函数,可以考虑用Stati c成员函数做线程函数.

【我解C语言面试题系列 】001 stati c有什么用途

【题目】 stati c有什么用 途

在网上流传很广的一个答案是

1、限制变量的作用域

2、设置变量的存储域

我觉得这样答题是不妥当的有点文不对题的感觉。

下面是我给出的答案stati c类型声明符在C语言里面主要有三个用途

<!--[if !suppo rtLis ts]-->1、 <!--[endif]-->声明静态局部变量。

<!--[if !suppo rtLis ts]-->2、 <!--[endif]-->声明静态外部全局变量。

<!--[if !suppo rtLis ts]-->3、 <!--[endif]-->声明静态外部函数。

下面是我整理的有关上面三个用法的解释说明。另外网友x iaoca i0001的

《stati c用法小结》一文有更详细的解释请参考。

[url]http://blog. csdn.net/xiaoc ai000 1/archi ve/2006/04/14/66292 1.aspx[/url]静态局部变量与auto对比

<!--[if !suppo rtLis ts]-->1、 <!--[endif]-->存储空间分配、作用域和生存期stati c分配在静态存储区作用域仅仅限于声明该变量的函数内部。在程序整个运行期间都不释放生存期贯穿于程序运行的整个过程。auto类型分配在栈上属于动态存储类别 占动态存储区空间作用域仅仅限于声明该变量的函数内部。函数调用结束后自动释放生存期不过是在声明该变量的函数内部。

2、赋初值时的处理方式stati c静态局部变量在编译时赋初值 即只赋初值一次auto自动变量赋初值是在函数调用时进行每调用一次函数重新给一次初值相当于执行一次赋值语句。

3、未赋初值时的处理方式

如果在定义局部变量时不赋初值的话

stati c静态局部变量编译时自动赋初值0 对数值型变量或空字符对字符变量 。auto自动变量如果不赋初值则它的值是一个不确定的值。

静态外部全局变量

在C语言中stati c还用来声明静态外部全局变量那么这个全局变量的作用域就被限制在本文件内部。

外部变量即全局变量是在函数的外部定义的它的作用域为从变量定义处开始到本程序文件的末尾。如果外部变量不在文件的开头定义其有效的作用范围只限于定义处到文件终了。如果在定义点之前的函数想引用该外部变量则应该在引用之前用关键字ext ern对该变量作“外部变量声明” 。表示该变量是一个已经定义的外部变量。有了此声明就可以从“声明”处起合法地使用该外部变量。

而如果我们声明的全局变量不想被其他文件访问和使用又该怎么办

那就是在声明的时候前面加上关键字stat ic。

静态外部函数

在C语言中我们的函数默认都是全局的也就是说你可以调用其他文件中的函数。在使用的时候我们象前面一样在头文件中加上e xtern就可以了。但是有时候我们写的函数并不想让别的文件访问和调用那么我们在声明函数的时候前面加上stat ic就可以了。

使用内部函数的好处有二

1、可以让某些内部函数不为人所能使用而仅仅让调用者使用他能使用的东西有利于保护代码。

2、不同的人编写不同的函数时不用担心自己定义的函数是否会与其它文件中的函数同名

tmhhost:暑假快乐,全高端线路,VPS直接8折,200G高防,美国gia日本软银韩国cn2香港cn2大带宽

tmhhost为2021年暑假开启了全场大促销,全部都是高端线路的VPS,速度快有保障。美国洛杉矶CN2 GIA+200G高防、洛杉矶三网CN2 GIA、洛杉矶CERA机房CN2 GIA,日本软银(100M带宽)、香港BGP直连200M带宽、香港三网CN2 GIA、韩国双向CN2。本次活动结束于8月31日。官方网站:https://www.tmhhost.com8折优惠码:TMH-SUMMER日本...

萤光云(16元/月)高防云服务器自带50G防御

螢光云官網萤光云成立于2002年,是一家自有IDC的云厂商,主打高防云服务器产品。在国内有福州、北京、上海、台湾、香港CN2节点,还有华盛顿、河内、曼谷等海外节点。萤光云的高防云服务器自带50G防御,适合高防建站、游戏高防等业务。本次萤光云中秋云活动简单无套路,直接在原有价格上砍了一大刀,最低价格16元/月,而且有没有账户限制,新老客户都可以买,就是直接满满的诚意给大家送优惠了!官网首页:www....

美国VPS 美国高防VPS 香港VPS 日本VPS 首月9元 百纵科技

百纵科技湖南百纵科技有限公司是一家具有ISP ICP 电信增值许可证的正规公司,多年不断转型探索现已颇具规模,公司成立于2009年 通过多年经营积累目前已独具一格,公司主要经营香港服务器,香港站群服务器,美国高防服务器,美国站群服务器,云服务器,母机租用托管!美国CN2云服务器,美国VPS,美国高防云主机,美国独立服务器,美国站群服务器,美国母机。美国原生IP支持大批量订货 合作 适用电商 亚马逊...

c语言static为你推荐
查看端口怎么查看服务器的端口手游运营手册2019新个税主要内容有哪些?可以简单说明一下吗?湖南商标注册湖南商标注册怎么办理1433端口路由器1433端口怎么开启安卓应用平台现在android平台的手机都有哪些?迅雷云点播账号求百度云或者迅雷云播账号密码电子商务网站模板电子商务网站策划书怎么上传音乐如何将电脑上的音乐传到MP3上微信怎么看聊天记录怎样才能调取微信聊天记录网站推广外链如何做网站推广 ,外链推广的方向在哪里?
域名是什么 个人域名注册 长春域名注册 河北服务器租用 域名查询工具 电信服务器租赁 怎么申请域名 a5域名交易 cloudstack ixwebhosting xfce 服务器怎么绑定域名 java空间 789电视网 网站卫士 免费活动 双线机房 腾讯总部在哪 免费asp空间 免费个人主页 更多