c语言 static的用法
static在c里面可以用来修饰变量,也可以用来修饰函数。
先看用来修饰变量的时候。变量在c里面可分为存在全局数据区、栈和堆里。其实我们平时所说的堆栈是栈而不是堆,不要弄混。
int a ;
int main()
{
int b ;
int c* = (int *)malloc(sizeof(int));
}
a是全局变量,b是栈变量,c是堆变量。
static对全局变量的修饰,可以认为是限制了只能是本文件引用此变量。有的程序是由好多.c文件构成。彼此可以互相引用变量,但加入static修饰之后,只能被本文件中函数引用此变量。
static对栈变量的修饰,可以认为栈变量的生命周期延长到程序执行结束时。一般来说,栈变量的生命周期由OS管理,在退栈的过程中,栈变量的生命也就结束了。但加入static修饰之后,变量已经不再存储在栈中,而是和全局变量一起存储。同时,离开定义它的函数后不能使用,但如再次调用定义它的函数时,它又可继续使用, 而且保存了前次被调用后留下的值。
static对函数的修饰与对全局变量的修饰相似,只能被本文件中的函数调用,而不能被同一程序其它文件中的函数调用。
static int i; //只在a文件中用
int j; //在工程里用
static void init() //只在a文件中用
{
}
void callme() //在工程中用
{
static int sum;
}
上面的全局i变量和init()函数只能用在a.c文件中,全局变量sum的作用域只在callme里。变量j和函数callme()的全局限扩充到整个工程文件。所以可以在下面的b.c中用extern关键字调用。extern告诉编译器这个变量或者函数在其他文件里已经被定义了。
extern int j; //调用a文件里的
extern void callme(); //调用a文件里的
int main()
{
...
}
extern的另外用法是当C和C++混合编程时如果c++调用的是c源文件定义的函数或者变量,那么要加extern来告诉编译器用c方式命名函数:
extern "C" //在c++文件里调用c文件中的变量
{
int j;
void callme();
}
int main()
{
callme();
}
二 static法则:
A、若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度;
B、若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度;
C、设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题;
注:耦合性(英语:Coupling,dependency,或称耦合力或耦合度)是一种软件度量,是指一程序中,模块及模块之间信息或参数依赖的程度。内聚性是一个和耦合性相对的概念,一般而言低耦合性代表高内聚性,反之亦然。耦合性和内聚性都是由提出结构化设计概念的赖瑞·康斯坦丁所提出。低耦合性是结构良好程序的特性,低耦合性程序的可读性及可维护性会比较好。
全局变量有外部、静态两种存储方式。
(1)全局变量一般用外部存储方式存储,用保留字extern加以定义。此时,变量的作用域是构成整个程序的所有程序文件,也就是定义的外部变量可供其它程序文件使用。
使用这样的全局变量一定要非常慎重,一旦产生错误,将波及整个程序。
(2)如果希望全局变量仅限于本程序文件使用,而其它程序文件中不能引用,这时必须将其存储方式定义为静态存储方式,用保留字static加以定义。此时称为静态外部变量。
例如,在上例文件filel.c中,如果作这样的定义:
static int a:
则变量a的作用域被缩小至本程序文件filel.c,文件file2.c中不能引用。
值得注意的是对全局变量加static,定义为静态存储方式,并不意味着是静态存储;而不加static,是动态存储。两种形式的全局变量(外部变量)都是静态存储方式,都是编译时分配存储空间,但作用域不同。使用静态外部变量,有利于隔离错误,有利于模块化程序设计。
(3)全局变量的缺省存储方式是外部存储方式。
前面章节中的程序没有见到变量的存储类别定义,实际上采用变量的缺省存储方式。对局部变量采用auto方式,对全局变量采用extern方式。这也是至今为止,我们在程序中没有见到auto、extern等的原因。
至此,我们对变量的存储类别及数据类型进行了全面讨论,在此作个小结。
1.变量定义的一般形式
存储类别数据类型变量表;
2.变量定义的作用
①规定了变量的取值范围。
②规定了变量进行的运行操作。
③规定了变量的作用域。
④规定了变量的存储方式。
⑤规定了变量占用的存储空间。
3.局部变量和全局变量
从作用域角度将变量分为局部变量和全局变量。它们采取的存储类别如下:
局部变量:
①自动变量,即动态局部变量(离开函数,值就消失)。
②静态局部变量(离开函数,值仍保留)。
③寄存器变量(离开函数,值就消失)。
④形式参数可以定义为自动变量或寄存器变量。
全局变量:
①静态外部变量(只限本程序文件使用)。
②外部变量(即非静态的外部变量,允许其它程序文件引用)。
4.动态存储和静态存储
从变量存在时间可将变量存储分为动态存储和静态存储。静态存储是在整个程序运行时都存在,而动态存储则是在调用函数时临时分配存储单元。
动态存储:
①自动变量(函数内有效)。
②寄存器变量(函数内有效)。
③形式参数。
静态存储:
①静态局部变量(函数内有效)。
②静态外部变量(本程序文件内有效)。
③外部变量(整个程序可引用)。
5.静态存储区和动态存储区
从变量值存放的位置可将变量存储区分为静态存储区和动态存储区:
内存中静态存储区:
①静态局部变量。
②静态外部变量。
③外部变量(可被同一程序其它文件引用)。
内存中动态存储区:自动变量和形式参数。
CPU中的寄存器:寄存器变量。
c语言 static的用法的更多相关文章
- 9.11 Django关于母版语言的灵活用法
2018-9-11 12:45:38 还是这个连接 : http://www.cnblogs.com/liwenzhou/p/7931828.html 注意: 这节讲的是 母版语言的灵活用法! 可 ...
- Java中static的用法
static静态,作为修饰符,最初是由c引入,一开始static表示退出一个块后依然存在的局部变量.随后,static表示不能被其他文件访问的全局变量和函数.到了C++和java,static表示属于 ...
- ava下static关键字用法详解
Java下static关键字用法详解 本文章介绍了java下static关键字的用法,大部分内容摘自原作者,在此学习并分享给大家. Static关键字可以修饰什么? 从以下测试可以看出, static ...
- C语言static 具体分析
google在最后三页C语言static内容,可找到的资料非常少.无论是长篇大论不知所云的话,在关键位置或跳过,习的人来说參考性不是非常大.所以.我这篇博文博採众家之长,把互联网上的资料整合归类,并亲 ...
- linux c语言 select函数用法
linux c语言 select函数用法 表头文件 #i nclude<sys/time.h> #i nclude<sys/types.h> #i nclude<unis ...
- C# static的用法详解
C# static的用法详解 有的东西你天天在用,但未必就代表你真正了解它,正如我之前所了解的 static . 一.静态类 静态类与非静态类的重要区别在于静态类不能实例化,也就是说,不能使用 n ...
- 单片机的C语言中位操作用法2
单片机的C语言中位操作用法 在对单处机进行编程的过程中,对位的操作是经常遇到的.C51对位的操控能力是非常强大 的.从这一点上,就可以看出C不光具有高级语言的灵活性,又有低级语言贴近硬件的特点. 这也 ...
- C语言-- static 全局使用示例
C语言-- static 全局使用示例 前言:看到很多使用Objective-C开发IOS的大牛,有时候会使用static全局变量,相比之下,我却很少用这个,从而很少对其有着比较有实质意义的理解,甚 ...
- C语言static关键字
C语言static关键字 static关键字的作用,主要从在程序的生存周期.作用域和在代码段中的位置起作用. 全局变量 静态全局变量 局部变量 静态局部量 生存周期 程序运行到结束 程序运行到结束 函 ...
随机推荐
- Pulsar 联合 TiDB 推出大数据场景数据应用分析解决方案
方案概述 大数据时代,各类应用对消息解决方案的要求不仅仅是数据的流动,而是要在持续增长的服务和应用中传输海量数据,进行智能的处理和分析,帮助业务做出更加精准的决策. Pulsar 与 TiDB 联合解 ...
- android开发之java代码中如何获取到当前时间。详情代码带注释。
/** *获取当前时间 * @return */ public String getTime(){ Date date= new Date();//创建一个时间对象,获取到当前的时间 SimpleDa ...
- C#可空类型 T?
可空类型概述 可空类型具有以下特性: 可空类型表示可被赋值为 null 值的值类型变量.无法创建基于引用类型的可空类型.(引用类型已支持 null 值.). 语法 T? 是 System.Nullab ...
- Unity动态绑定按钮触发方法
在使用unity制作UI的过程中,基本都需要接触到按钮,然后按钮要起作用的话,那么就需要为按钮绑定响应方法. 为按钮绑定触发的方法,我知道的有两种方法,第一种:手动使用unityEditor 绑定,另 ...
- 【Gin-API系列】实现路由分组(七)
在之前的文章介绍中我们已经完成了一个API服务的全链路请求设计.调用方式可以看Test目录的代码 // src/test/request_test.go func TestAPI_Request(t ...
- libtorrent资料整理
源码libtorrent源码地址:https://github.com/arvidn/libtorrent/releases libtorrent Java库地址:https://github.com ...
- directives 自定义指令
钩子函数 一个指令定义对象可以提供如下几个钩子函数 (均为可选): bind:只调用一次,指令第一次绑定到元素时调用.在这里可以进行一次性的初始化设置.基本数据类型如果发生改变,不会触发,但是引用数据 ...
- 一文看懂 YAML
前言 YAML 并不是一种新奇的语言,YAML 首次发表于 2001 年,距离现在已经过去差不多 20 个年头.YAML 虽然不如 JSON.XML 之类的语言流行,应用也没有那么广泛,但是 YAML ...
- Oracle中真正稳妥的求三甲的方法
坐地铁回家路上忽然想起,三甲排名可能为多个,只取三名岂不荒谬.不信请看下面数据: create table tb_score( id number(4,0) primary key, name nva ...
- mysql jdbc连接时的小问题java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES)
这次重新修改老程序时出现了上面的错误,排查过后最终找到问题所在:root帐户默认不开放远程访问权限,所以需要修改一下相关权限. 打开MySQL目录下的my.ini文件(win10默认安装在C:\Pro ...