1.小气的static
对于学习C语言的人来说,如果突然间提问:statci有哪些用法?我们当中的大部分人往往说不清楚。不仅说不清楚,事实上,对于“什么是static?”、"为什么要使用static",初学者通常都不是很了解的。
关于static的用法,我们首先通过生活中的一个简单的例子加以类比,然后针对这些例子再为大家进行简单的说明。
傻孩子历经千辛万苦,通过打工积攒到足够的钱,买了一个MP4。各路朋友闻讯赶来,都要看看“MP4中的月亮比起电脑显示器究竟有多圆”。小气的傻孩子规定:MP4除了本寝室的是有以外(面子上过不去)“概不外借!”。
与之相似,一个C语言模块(.c)里面包含了一些全局变量和函数。如果开发者希望这些变量和函数只能在模块中使用,而模块外的程序没有任何权限访问和调用,它应该怎么做呢?
//Example.c模块
//在模块外部可以通过extern unsigned chae NumbeiA来引用的变量
unsigned chae NumberA=0;
...
//通过static限制:只能在模块内部使用,外部没有权限访问的变量
static unsigned char NumberB = 0;
...
//在模块外部可以通过extern void FunctionA(void)来引用的函数
void FunctionA(void);
...
//通过static限制:只能被模块内部其他函数调用,外部没有使用权限
static void FunctionB(void);
...
对于例子中的变量NumberA和函数FunctionA,由于没有加入static限制,因此外部可以增加额外引用后(例如extern NumberA或者extern void FunctionA(void))直接访问。对于增加了static限定的变量和函数来说,外部的任何企图都是非法的,编译器会在程序的语法检测阶段给出警告。
再比如:
傻孩子的MP4不仅可以玩游戏,而且还具有每次退出游戏时自动保存游戏进度的功能。完毕这些变量就会释放,各类计算机数据也会随之“灰飞烟灭”。如果我们想保存某些变量内容--直到函数下一次调用时仍然有效,应该怎么实现呢?
//一个使用静态局部变量的函数例子
void Function(void)
{
unsigned char CounterA=0;//普通局部变量
static unsigned char CounterB=0;//静态局部变量
...
CounterA++;
CounterB++;
...
}
分析上面的函数,CounterA是一个普通局部变量:每次函数被执行时,都会被声明一次为1--分配一个空间并将值初始化为0,因此,语句CounterA被执行以后,其只值始终都只能为1.当然,在函数执行完成以后,该变量所临时占用的空间也将被释放。CounterB是一个静态局部变量:它只会在函数第一次执行时被分配一个空间并将结果初始化为0。而以后函数每次被调用,初始化操作都会被跳过。由于在函数每次执行完成以后,该变量占用的空间并不会被释放,因此变量的内容也不会丢失--随着语句CounterB++的执行,变量的值一直递增(知道超过255以后移出为0)。
静态局部变量是局部变量,因此,函数体以外的地方是没权限对其进行访问的。之所以我们要强调这个问题,是因为静态局部变量可以被简单地等效为一个“只能在某一个函数中被访问的全局变量”。