做用域 全局变量 局部变量 静态变量 外部变量 常量 volatile变量html 做用域:ios 做用域规则告诉咱们一个变量的有效范围,它在哪儿建立,在哪儿销毁(也就是说超出了做用域)。变量的有效做用域从它的定义点开始,到和定义变量以前最邻近的开括号配对的第一个闭括号。也就是说,做用域由变量所在的最近一对括号肯定。程序员 全局变量:数组 全局变量是在全部函数体的外部定义的,程序的所在部分(甚至其它文件中的代码)均可以使用。全局变量不受做用域的影响,问题可使用的(也就是说,全局变量的生命期一直到程序的结束)。若是在一个文件中使用extern关键字来声明另外一个文件中存在的全局变量,那么这个文件可使用这个数据。函数 局部变量:post 局部变量出如今一个做用域内,它们是局限于一个函数的。局部变量常常被称为自动变量,由于它们在进入做用域时自动生成,离开做用域时自动消失。关键字auto能够显式地说明这个问题,可是局部变量默认为优化 auto,因此没有必要声明为auto。spa 寄存器变量设计 寄存器变量是一种局部变量。关键字register告诉编译器“尽量快地访问这个变量”。加快访问速度取决于现实,可是,正如名字所暗示的那样,这常常是经过在寄存器中放置变量来作到的。这并不能保证将变置在寄存器中,甚至也不能保证提升访问速度。这只是对编译器的一个暗示。指针 使用register变量是有限制的。不可能获得或计算register 变量的地址。register变量只能在一个块中声明(不可能有全局的或静态的register变量)。然而能够在一个函数中(即在参数表中)使用register变量做为一个形式参数。 通常地,不该当推测编译器的优化器,由于它可能比咱们作得更好。所以,最好避免使用关键字register。 静态变量 关键字static有一些独特的意义。一般,函数中定义局部变量在函数中做用域结束时消失。当再次调用这个函数时,会从新建立变量的存储空间,其值会被从新初始化。若是想使局部变量的值在程序的整个生命期里仍然存在,咱们能够定义函数的局部变量为static(静态的),并给它一个初始化。初始化只在函数第一次调用时执行,函数调用之间变量的值保持不变,这种方式,函数能够“记住”函数调用之间的一些信息片段。 咱们可能奇怪为何不使用全局变量。static变量的优势是在函数范围以外它是不可用的,因此它不可能被轻易改变。这会使错误局部化。 外部变量 extern告诉编译器存在着一个变量和函数,即便编译器在当前的文件中没有看到它。这个变量或函数可能在一个文件或者在当前文件的后面定义。例如extern int i;编译器会知道i确定做为全局变量存在于某处。当编译器看到变量i的定义时,并无看到别的声明,因此知道它在文件的前面已经找到了一样声明的i 。 常量 const告诉编译器这个名字表示常量,无论是内部的仍是用户定义的数据类型均可以定义为const。若是定义了某对象为常量,而后试图改变它,编译器将会产生错误。在C++中一个const必须有初始值。 volatile变量 限定词const告诉编译器“这是不会改变的”(这就是容许编译器执行额外的优化);而限定词volatile则告诉编译器“不知道什么时候变化”,防止编译器依据变量的稳定性做任何优化。 参考《Thinking in C++》第一卷第三章 |
——————————————————————————————————————
1.先来介绍它的第一条也是最重要的一条:隐藏
当咱们同时编译多个文件时,全部未加static前缀的全局变量和函数都具备全局可见性。为理解这句话,我举例来讲明。咱们要同时编译两个源文件,一个是a.c,另外一个是main.c.
下面是a.c的内容:
char a = 'A'; // global variable |
下面是main.c的内容:
int main(void) |
程序的运行结果是:
A Hello
你可能会问:为何在a.c中定义的全局变量a和函数msg能在main.c中使用?前面说过,全部未加static前缀的全局变量和函数都具备全局可见 性,其它的源文件也能访问。此例中,a是全局变量,msg是函数,而且都没有加static前缀,所以对于另外的源文件main.c是可见的。
若是加了static,就会对其它源文件隐藏。例如在a和msg的定义前加上 static,main.c就看不到它们了。利用这一特性能够在不一样的文件中定义同名函数和同名变量,而没必要担忧命名冲突。Static能够用做函数和变 量的前缀,对于函数来说,static的做用仅限于隐藏,而对于变量,static还有下面两个做用。
2. static的第二个做用是保持变量内容的持久
存储在静态数据区的变量会在程序刚开始运行时就完成初始化,也是惟一的一次初始化。共有两种变量存储在静态存储区:全局变量和static变量,只不过和 全局变量比起来,static能够控制变量的可见范围,说到底static仍是用来隐藏的。虽然这种用法不常见,但我仍是举一个例子。
#include <stdio.h> |
程序的运行结果是:
global local static
1 10
2 9
3 8
4 7
5 6
6 5
7 4
8 3
9 2
10 1
3. static的第三个做用是默认初始化为0.其实全局变量也具有这一属性,由于全局变量也存储在静态数据区
在静态 数据区,内存中全部的字节默认值都是0x00,某些时候这一特色能够减小程序员的工做量。好比初始化一个稀疏矩阵,咱们能够一个一个地把全部元素都置0, 而后把不是0的几个元素赋值。若是定义成静态的,就省去了一开始置0的操做。再好比要把一个字符数组当字符串来用,但又以为每次在字符数组末尾加‘\0’ 太麻烦。若是把字符串定义成静态的,就省去了这个麻烦,由于那里原本就是‘\0’。不妨作个小实验验证一下。
#include <stdio.h> |
程序的运行结果以下integer: 0; string: (begin)(end)
最后对static的三条做用作一句话总结。首先static的最主要功能是隐藏,其次由于static变量存放在静态存储区,因此它具有持久性和默认值0.
4. 用static声明的函数和变量小结
static 声明的变量在C语言中有两方面的特征:
1)、变量会被放在程序的全局存储区中,这样能够在下一次调用的时候还能够保持原来的赋值。这一点是它与堆栈变量和堆变量的区别。
Tips:
A.若全局变量仅在单个C文件中访问,则能够将这个变量修改成静态全局变量,以下降模块间的耦合度;
B.若全局变量仅由单个函数访问,则能够将这个变量改成该函数的静态局部变量,以下降模块间的耦合度;
C.设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,须要考虑重入问题;
D.若是咱们须要一个可重入的函数,那么,咱们必定要避免函数中使用static变量(这样的函数被称为:带“内部存储器”功能的的函数)
E.函数中必需要使用static变量状况:好比当某函数的返回值为指针类型时,则必须是static的局部变量的地址做为返回值,若为auto类型,则返回为错指针。
函数前加static使得函数成为静态函数。但此处“static”的含义不是指存储方式,而是指对函数的做用域仅局限于本文件(因此又称内部函数)。使用内部函数的好处是:不一样的人编写不一样的函数时,不用担忧本身定义的函数,是否会与其它文件中的函数同名。
扩展分析:
术语static有着不寻常的历史.起初,在C中引入关键字static是为了表示退出一个块后仍然存在的局部变量。随后,static在C中有了第二种含义:用来表示不能被其它文件访问的全局变量和函数。为了不引入新的关键字,因此仍使用static关键字来表示这第二种含义。最后,C++重用了这个关键字,并赋予它与前面不一样的第三种含义:表示属于一个类而不是属于此类的任何特定对象的变量和函数(与Java中此关键字的含义相同)。
全局变量、静态全局变量、静态局部变量和局部变量的区别
变量能够分为:全局变量、静态全局变量、静态局部变量和局部变量。
全局变量(外部变量)的说明以前再冠以static 就构成了静态的全局变量。全局变量自己就是静态存储方式, 静态全局变量固然也是静态存储方式。 这二者在存储方式上并没有不一样。这二者的区别虽在于非静态全局变量的做用域是整个源程序, 当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其做用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。因为静态全局变量的做用域局限于一个源文件内,只能为该源文件内的函数公用, 所以能够避免在其它源文件中引发错误。
从以上分析能够看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的做用域, 限制了它的使用范围。
static 函数与普通函数做用域不一样。仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static),内部函数应该在当前源文件中说明和定义。对于可在当前源文件之外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件
static全局变量与普通的全局变量有什么区别:static全局变量只初始化一次,防止在其余文件单元中被引用;
static局部变量和普通局部变量有什么区别:static局部变量只被初始化一次,下一次依据上一次结果值;
static函数与普通函数有什么区别:static函数在内存中只有一份,普通函数在每一个被调用中维持一份拷贝
全局变量和静态变量若是没有手工初始化,则由编译器初始化为0。局部变量的值不可知。
——————————————————————————————————————
C++的static有两种用法:面向过程程序设计中的static和面向对象程序设计中的static。前者应用于普通变量和函数,不涉及类;后者主要说明static在类中的做用。
1、面向过程设计中的static
1、静态全局变量
在全局变量前,加上关键字static,该变量就被定义成为一个静态全局变量。咱们先举一个静态全局变量的例子,以下:
//Example 1
#include <iostream.h>
void fn();
static int n; //定义静态全局变量
void main()
{
n=20;
cout<<n<<endl;
fn();
}
void fn()
{
n++;
cout<<n<<endl;
}
静态全局变量有如下特色:
·
1 该变量在全局数据区分配内存;
·
未经初始化的静态全局变量会被程序自动初始化为0(自动变量的值是随机的,除非它被显式初始化);
·
静态全局变量在声明它的整个文件都是可见的,而在文件以外是不可见的;
静态变量都在全局数据区分配内存,包括后面将要提到的静态局部变量。对于一个完整的程序,在内存中的分布状况以下图:
代码区 |
全局数据区 |
堆区 |
栈区 |
通常程序的由new产生的动态数据存放在堆区,函数内部的自动变量存放在栈区。自动变量通常会随着函数的退出而释放空间,静态数据(即便是函数内部的静态局部变量)也存放在全局数据区。全局数据区的数据并不会由于函数的退出而释放空间。细心的读者可能会发现,Example 1中的代码中将
static int n; //定义静态全局变量
改成
int n; //定义全局变量