函数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、不同的人编写不同的函数时不用担心自己定义的函数是否会与其它文件中的函数同名

Sharktech:鲨鱼机房1Gbps无限流量美国服务器;丹佛$49/月起,洛杉矶$59/月起

sharktech怎么样?sharktech鲨鱼机房(Sharktech)我们也叫它SK机房,是一家成立于2003年的老牌国外主机商,提供的产品包括独立服务器租用、VPS主机等,自营机房在美国洛杉矶、丹佛、芝加哥和荷兰阿姆斯特丹等,主打高防产品,独立服务器免费提供60Gbps/48Mpps攻击防御。机房提供1-10Gbps带宽不限流量服务器,最低丹佛/荷兰机房每月49美元起,洛杉矶机房最低59美元...

远程登录VNC无法连接出现

今天有网友提到自己在Linux服务器中安装VNC桌面的时候安装都没有问题,但是在登录远程的时候居然有出现灰色界面,有三行代码提示"Accept clipboard from viewers,Send clipboard to viewers,Send primary selection to viewers"。即便我们重新登录也不行,这个到底如何解决呢?这里找几个可以解决的可能办法,我们多多尝试。...

DogYun春节优惠:动态云7折,经典云8折,独立服务器月省100元,充100送10元

传统农历新年将至,国人主机商DogYun(狗云)发来了虎年春节优惠活动,1月31日-2月6日活动期间使用优惠码新开动态云7折,经典云8折,新开独立服务器可立减100元/月;使用优惠码新开香港独立服务器优惠100元,并次月免费;活动期间单笔充值每满100元赠送10元,还可以参与幸运大转盘每日抽取5折码,流量,余额等奖品;商家限量推出一款年付特价套餐,共100台,每个用户限1台,香港VPS年付199元...

c语言static为你推荐
iphone360手机卫士苹果手机支持360手机卫士吗?jolicloud怎么安装linux系统?ip地址是什么正确的IP地址是什么淘宝客推广淘宝客推广有哪些途径阿里云系统阿里云系统怎么样好用吗?吴晓波频道买粉五大知识付费平台有哪些?ios7固件下载ios 7及以上固件请在设备上点信任在哪点ios7固件下载iOS7如何升级固件?畅想中国20年后中国会变成什么样?--畅想一下未来的中国!!怎么点亮qq空间图标QQ空间图标怎么点亮?
重庆服务器租用 大庆服务器租用 万网域名代理 企业主机 awardspace 10t等于多少g l5520 双11抢红包攻略 天猫双十一秒杀 win8.1企业版升级win10 ev证书 java空间 免费网站申请 php空间申请 web服务器架设 卡巴斯基官方免费版 申请个人网站 网络空间租赁 linux服务器维护 1美金 更多