术语static有着不寻常的历史.起初,在C中引入关键字static是为了表示退出一个块后仍然存在的局部变量。随后,static在C中有了第二种含义:用来表示不能被其它文件访问的全局变量和函数。为了避免引入新的关键字,所以仍使用static关键字来表示这第二种含义。最后,C++重用了这个关键字,并赋予它与前面不同的第三种含义:表示属于一个类而不是属于此类的任何特定对象的变量和函数。
第一种作用:
程序开始时为静态变量分配空间,结束时释放空间,默认初始化为0,使用时可以改变其值。
// demo001_001.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <windows.h> int fun(void) { static int count = 10; // 程序开始初始化一次,之后不会再执行,作用域在fun函数里面,盛名周期是整个程序 return count--; } int count; //全局变量,和静态的count不是同一个变量,默认初始化为0 int _tmain(int argc, _TCHAR* argv[]) { printf("global\t\tlocal static\n"); for (; count <= 10; ++count) printf("%d\t\t%d\n", count, fun()); system("pause"); return 0; }
第二种作用:
静态变量或静态函数只有在它的作用域才能访问它,它的名字在其它文件中不可见。
为什么第一种作用中,整个生命周期都存在的count和全局变量count同名,却没有冲突?这就是static的第二个作用,隐藏。
// stdafx.cpp : 只包括标准包含文件的源文件 #include "stdafx.h" static int number = 100; //全局静态变量,作用域是当前文件 int count = 100; //全局变量,作用域是整个项目 void show() //全局函数,作用域是整个项目 { printf("6666666666\n"); }
// demo001_001.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <windows.h> extern int count; //声明,extern关键第二例会说明 extern void show(); //声明,extern关键第二例会说明 extern int number; //错误,number只能在stdafx.cpp被访问 int _tmain(int argc, _TCHAR* argv[]) { printf("%d\n",count); show(); system("pause"); return 0; }
static将变量和函数都隐藏在他们的作用域,外面访问不到。
第三种作用:
直接使用类,不需要具体的对象,就可以使用静态成员变量和静态函数。
static void show(){}; //类的静态方法,可以直接被类调用 DemoClass::show();
扩展一下:
C、C++中内存分配方式可以分为三种:
(1)从静态存储区域分配:
内存在程序编译时就已经分配好,这块内存在程序的整个运行期间都存在。速度快、不容易出错,因为有系统会善后。例如全局变量,static变量等。
(2)在栈上分配:
在执行函数时,函数内局部变量的存储单元都在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
(3)从堆上分配:
即动态内存分配。程序在运行的时候用malloc或new申请任意大小的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由程序员决定,使用非常灵活。如果在堆上分配了空间,就有责任回收它,否则运行的程序会出现内存泄漏,另外频繁地分配和释放不同大小的堆空间将会产生堆内碎块。
一个C、C++程序编译时内存通常认为会分为5大存储区:堆区、栈区、全局区、文字常量区、程序代码区等。
全局变量、静态全局变量、静态局部变量和局部变量的区别
变量可以分为:全局变量、静态全局变量、静态局部变量和局部变量。
(1) 按存储区域分,全局变量、静态全局变量和静态局部变量都存放在内存的静态存储区域,局部变量存放在内存的栈区。
(2) 按作用域分,全局变量在整个工程文件内都有效;静态全局变量只在定义它的文件内有效;静态局部变量只在定义它的函数内有效,只是程序仅分配一次内存,函数返回后,该变量不会消失;局部变量在定义它的函数内有效,但是函数返回后失效。
全局变量(外部变量)的说明之前再冠以static就构成了静态的全局变量。全局变量本身就是静态存储方式,静态全局变量当然也是静态存储方式。这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。
从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域, 限制了它的使用范围。