静态局部变量、静态全局变量、extern全局变量、自动变量 札记
- 静态局部变量
静态局部变量。
从称呼上我们可以看出,静态局部变量首先是一个局部变量,因此其只在定义它的函数内有效,冠以静态的头衔后,其生存期就被延长了,不会随着函数的返回而被撤销。我们可以这样来理解:静态局部变量就是在程序生存期间一直有效,但只能在定义它的函数中使用的一种变量。
静态局部变量的声明比较简单,在声明局部变量的时候,加上关键字static就可以了。下面是一个用局部静态变量计算阶乘的具体例子。
#include “stdio.h” int fac(int n)
{
static int nRet = 1; //静态局部变量 nRet *= n; return nRet;
} void main()
{
for(int i=1;i<5;i++)
{
printf(“%d!=%d\n“,i,fac(i));
}
getchar();
}
在第一次调用函数fac的时候,函数fac中的静态局部变量nRet被初始化为1,如果没有默认指定初始化值得话,会被默认初始化为0. 主函数main中共进行了4次fac函数的调用:
第一次调用:初始化nRet为1 函数返回时:nRet=1
第二次调用时: nRet=1 函数返回时:nRet=2
第三次调用时: nRet=2 函数返回时:nRet=6
第四次调用时: nRet=6 函数返回时:nRet=24
可以看出,静态局部变量在第一次调用的时候进行初始化,每次函数调用后,静态局部变量不会像局部变量那样被立即释放,而是继续有效,在下一次函数调用的时候会继续使用上一次的值。
静态局部变量总结:
(1)静态局部变量可以不初始化,有系统设置默认值为0;
(2)静态局部变量默认只会在最开始定义静态局部变量时初始化,并且只有这唯一的一次初始化;
(3)静态局部变量的作用范围仅仅只是块(如函数)内部。
2.静态局部变量与其他变量类型的关系
全局变量具有全局作用域。全局变量只需在一个源文件中定义,就可以作用于所有的源文件。当然,其他不包含全局变量定义的源文件需要用extern 关键字再次声明这个全局变量。
静态局部变量具有局部作用域,它只被初始化一次,自从第一次被初始化直到程序运行结束都一直存在,它和全局变量的区别在于全局变量对所有的函数都是可见的,而静态局部变量只对定义自己的函数体始终可见。
局部变量也只有局部作用域,它是自动对象(auto),它在程序运行期间不是一直存在,而是只在函数执行期间存在,函数的一次调用执行结束后,变量被撤销,其所占用的内存也被收回。
静态全局变量也具有全局作用域,它与全局变量的区别在于如果程序包含多个文件的话,它作用于定义它的文件里,不能作用到其它文件里,即被static关键字修饰过的变量具有文件作用域。这样即使两个不同的源文件都定义了相同名字的静态全局变量,它们也是不同的变量。
从分配内存空间看: 全局变量,静态局部变量,静态全局变量都在静态存储区分配空间,而局部变量在栈里分配空间。
使用的tips:
Tips:
A.若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度;
B.若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度;
C.设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题,因为他们都放在静态数据存储区,全局可见;
D.如果我们需要一个可重入的函数,那么,我们一定要避免函数中使用static变量(这样的函数被称为:带“内部存储器”功能的的函数)
E.函数中必须要使用static变量情况:比如当某函数的返回值为指针类型时,则必须是static的局部变量的地址作为返回值,若为auto类型,则返回为错指针。
3. static VS auto, static 全局变量 VS extern 全局变量
和局部static相反的保留字是auto(一般可以不写,我们通常声明的变量,如 int a =19, 等,就是auto变量),static变量的生存期是永久(对于我们可见的代码来说),只初始化一次;而auto变量的生存期与所在块(复合语句)相同,每次进入块时进行初始化,
如果是对象类型则在声明的地方执行构造语句。
全局static变量是这样的:
static int a;
main()
{
...
}
这时和它相反的是extern,这时static表明这个全局变量是“文件级”的,只能在这个文件中可见,但生存期和其它全局变量相同。
4.从作用域的角度考虑
extern全局变量、static全局变量和static局部变量的生存期都是“永久”(即:程序存在期间一直都可以使用),区别只是可见域不同。extern全局变量可见区域是工程,static全局变量可见区域是文件,而static局部变量的可见区域是块。
从代码维护角度来看,对extern变量的修改可能会影响所有代码,对static全局变量的修改可能影响一个文件中的代码,而对static变量的修改可能影响一个块的代码;因此在选择变量类型时,优先级是static局部>static全局>extern全局。但它们有着共同的缺点:使用了这些类型变量的函数将是不可重入的,不是线程安全的。在C/C++标准库中有很多函数都使用了static局部变量,目前的实现中都为它们提供了两套代码,单线程版本使用static变量而多线程版本使用“线程全局变量”,比如rand,strtok等。
5.自动变量示例
自动变量:局部没有经过任何修饰的局部变量叫自动变量 (它存在于动态数据区——栈),这个区域内的数据随着程序的运行动态的生成和释放,函数返回就释放,函数要调用就生成。关键字:默认是atuo(一般不写).
自动变量的特点:当程序执行到自动变量的作用域的时候就分配,不是到了声明代码才分配哦!到了代码分配就晚啦!当定义自动变量的函数执行结束后,程序将释放该自动变量的存储空间,留给其他自动变量使用。
#include <stdio.h> void add(int n)
{
auto int s = 0;
s = s + 1; printf("No.%d: s=%d\n", n, s);
} void main()
{
int i = 1; for(i; i<4; i++)
{
add(i);
}
}
输出为:
No.1: s=1 No.2: s=1 No.3: s=1
从这个例子不难看出,自动变量的初始值在每次分配存储空间后都要重新赋值。
静态局部变量、静态全局变量、extern全局变量、自动变量 札记的更多相关文章
- PHP static静态局部变量和静态全局变量总结
1.不会随着函数的调用和退出而发生变化,不过,尽管该变量还继续存在,但不能使用它.倘若再次调用定义它的函数时,它又可继续使用,而且保存了前次被调用后留下的值 2.静态局部变量只会初始化一次 3.静态属 ...
- C++ 全局变量、局部变量、静态全局变量、静态局部变量的区别
全局变量.局部变量.静态全局变量.静态局部变量的区别 C++变量根据定义的位置的不同的生命周期,具有不同的作用域,作用域可分为6种:全局作用域,局部作用域,语句作用域,类作用域,命名空间作用域和文件作 ...
- C语言中全局变量、局部变量、静态全局变量、静态局部变量的区别 (转)
1.C++变量根据定义的位置的不同的生命周期,具有不同的作用域,作用域可分为6种: 全局作用域,局部作用域,语句作用域,类作用域,命名空间作用域和文件作用域. 从作用域看: 1>全局变量具有全局 ...
- c语言局部变量 静态局部变量 全局变量与静态全局变量
基本概念: 作用域:起作用的区域,也就是可以工作的范围. 代码块:所谓代码块,就是用{}括起来的一段代码. 数据段:数据段存的是数,像全局变量就是存在数据段的 代码段:存的是程序代码,一般是只读的. ...
- IOS总结 静变量static、全局变量extern、局部变量、实例变量
1.静态变量 static 什么是静态变量:从面向对象的角度触发,当需要一个数据对象为整类而非某个对象服务,同时有力求不破坏类的封装性,既要求此成员隐藏在类的内部,有要求对外不可见的时候,就可以使用s ...
- C++中的全局变量、普通局部变量和静态局部变量的区别
在C++中,我们经常难以说清楚全局变量.局部变量和静态局部变量的区别.本博客从变量存储特性和标识符作用域两个角度区分这三个变量. 首先,我们来看看C++程序的内存区域是如何分配的. 从上图,我们可以看 ...
- C语言 全局变量、静态全局变量、局部变量、静态局部变量
//test.c #include <stdio.h> extern int global_var; void test_global_var() { global_var++; prin ...
- static静态全局变量和static静态局部变量
static静态全局变量: 静态全局变量就是将全局变量变成静态的.如何变?——全局变量加个static. static就是一个存储类说明符,a这个全局变量就成了一个静态全局变量了. 静态全局变量的特点 ...
- C++静态全局变量和全局变量的区别
静态全局变量 非静态全局变量 存储方式 静态存储 静态存储 作用域 定义该变量的源文件内 所有源文件 解释: 共同点:全局变量(外部变量)的说明之前再冠以static 就构 成了静态的全局变量.全 ...
随机推荐
- 【mongo】pymongo通过_id删除数据
来源:http://www.educity.cn/wenda/361741.html pymongo 根据 objectId _id 来删除数据想要删除数据,根据_id ,是最靠谱的,具体方法因为 _ ...
- Jquery 提示还可以输入的字数,将多余的字数截取掉
js代码: $(function () { var counter = $("#divform textarea").val().length; //获取文本域的字符串长度 $( ...
- SQL语句题库
一. 填空题 Not Only SQL数据库 泛指 非关系型数据库 . SYS和SYSTEM用户都是Oracle 的系统用户,它们都使用SYSTEM表空间,其中 sys 拥有更大的权限. O ...
- supersr--打电话/短信分享/邮件分享
// Created by apple on 15/6/17. // Copyright (c) 2015年 Super All rights reserved. // #import " ...
- 八皇后(dfs+回溯)
重看了一下刘汝佳的白板书,上次写八皇后时并不是很懂,再写一次: 方法1:逐行放置皇后,然后递归: 代码: #include <bits/stdc++.h> #define MAXN 8 # ...
- Jquery.Datatables 导出excel
按钮(Buttons) BUttons v1.1.2 下载地址:http://pan.baidu.com/s/1c0Jhckg JSZip v2.5.0-21-g4fd4fc1 下载地址:http:/ ...
- jquery文件上传控件 Uploadify 问题记录
Uploadify v3.2.1 首先引用下面的文件 <!--上传控件 uploadify--> <script type="text/javascript" s ...
- 使用 Laravel 框架:成为微信公众平台开发者
转: http://ninghao.net/blog/1441 作者:王皓发布于:2014-05-30 13:16更新于:2014-05-31 12:05 我们可以使用Laravel 框架为微信公众平 ...
- Shell编程基础教程7--脚本参数的传递
7.脚本参数的传递 7.1.shift命令 简介: shift n 每次将参数位置向左偏移n位 例子 #!/bin/bash us ...
- 图结构练习——最小生成树(kruskal算法(克鲁斯卡尔))
图结构练习——最小生成树 Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^ 题目描述 有n个城市,其中有些城市之间可以修建公路,修建不同的公 ...