7.1C/C++关键字
7.1.1static(静态)变量有什么作用
关键字static的3个明显的作用:(1)在函数体内,静态变量具有“记忆”功能,即一个被声明为静态的变量在这一函数被调用的过程中其值维持不变。(2)在模块内(但在函数体外),他的作用域范围是有限制的,即如果一个变量被声明为静态的,那么该变量可以被模块内的所有函数访问,但不能被模块外的其他函数访问。他是一个本地的全局变量,如果一个函数被声明为静态的,那么该函数与普通函数作用域不同,其作用域仅在本文件中,他只可被这一模块内的其他函数调用,不能被模块外的其他函数调用,也就是说这个函数被限制在声明他的模块的本地范围内使用。(3)内部函数应该在当前源文件中说明和定义,对于可在当前源文件以外使用的函数,应该在一个头文件说明,使用这些函数的源文件要包含这个头文件。
static全局变量和普通的全局变量的区别在于static全局变量值初始化一次,这样做的目的是为了防止在其他文件单元中被引用。static局部变量和普通局部变量的区别在于static局部变量只被初始化一次,下一次的运算依据上一次的结果值。static()函数与普通函数的区别在于作用域不一样,static()函数只在一个源文件中有效,不能被其他源文件使用。
静态数据成员的特点:
(1),对于每个非静态数据成员,每个类对象都有自己的复制品。而静态数据成员被当作是类的成员。无论这个类的对象被定义了多少个,静态数据成员在程序中也只有一份复制品,由该类型的所有对象共享访问。
(2),静态数据成员存储在全局数据区。定义是要分配空间,所以不能在类声明中定义。由于静态数据成员属于本类的所有对象共享,所以他不属于特定的类对象,在没有产生类对象时其作用域就可见,即在没有产生类的实例时,程序员也可以使用他。
(3),静态数据成员和普通数据成员一样遵从public、protected、private访问规则。
(4),static成员变量的初试化是在类外,此时不能再带上static的关键字private。protected的static成员虽然可以在类外初始化,但是不能在类外被访问。
与全局变量相比,使用静态数据成员有以下两个优势:
(1),静态数据成员没有进入程序的全局名字空间,因此不存在与程序中其他全局名字冲突的可能性。
(2),可以实现信息的隐藏。静态数据成员可以是private成员,而全局变量不能。
类的静态成员必须初始化,因为他是在程序初始化的时候分配的。类中只是声明,在cpp中才是初始化,可以在初始化的代码上放个断点,在程序执行到main()的第一条语句之前就会先走到那儿。如果静态成员是个类,那么就会调用到他的构造函数。
与静态数据成员一眼个,当类的成员函数前面添加了static关键字后就变为了类的静态成员函数,静态成员函数为类的全部服务而不是为某一个类的具体对象服务。静态成员函数是类的内部实现,属于类定义的一部分。普通的成员函数一般都隐含了一个this指针,this指针指向类的对象本身,以为普通成员函数总是具体的属于某个类的具体对象的。通常情况下,this是默认的。如函数fn()实际上是this->fn()。但是与普通函数相比,静态成员函数由于不是与任何对象相联系,因此他不具有this指针。从这个意义上讲,他无法访问属于类对象的非静态数据成员,也无法访问非静态成员函数,他只能调用其余的静态成员函数。
引申1:static变量只初始化一次。
静态变量初始化后,一直没有被销毁,都会被保存在内存区域中,一般与整个源程序“同生存、共存亡”。
而auto变量,即自动变量,由于存放在栈区,一旦调用过程结束,就会被立刻销毁。
程序1:
#include <stdlib.h>
#include <stdio.h>
void fun(int i)
{
static int value=i++;
printf("%d\n",value);
}
int main()
{
fun(0);
fun(1);
fun(2);
system("pause");
return 0;
}
程序输出为
0
0
0
请按任意键继续...
程序每次输出都为0,是因为value是静态类型(static),只会定义一次。也就是说不管调用fun()这个函数多少次,static int value=i++;这个定义语句只会在第一次调用时候执行,由于第一次执行的时候i=0,所以value也就被初始化成0了,以后调用fun()都不会再执行这条语句了。
程序2:
#include <stdlib.h>
#include <stdio.h>
void fun(int i)
{
static int value=i++;
value=i++;
printf("%d\n",value);
}
int main()
{
fun(0);
fun(1);
fun(2);
system("pause");
return 0;
}
程序输出为
1
1
2
请按任意键继续...
上述代码之所以输出为1,1,2,是因为当调用fun(0)时,由于value被声明为static,所以定义语句只执行了一次,此时value=i++,value的值为0,i的值变为1,执行第二行语句value=i++后,此时value的值为i的初始值1,接着i的值变为2,所以第一次输出为1。当调用fun(1)时,因为value是静态变量,具有记忆功能,所以会跳过定义语句,只执行value=i++语句,所以value的值为1,而此时i的值变为2,所以第二次调用时输出为1。当调用fun(2)的时候,也会跳过定义语句,只执行vlalue=i++语句,所以value的值为2,i的值为3,所以第三次调用时输出为2。
引申2:是否可以在头文件中定义静态变量
不可以,在头文件中定义静态变量,会造成资源浪费的问题,同时也可能引起程序错误。因为如果在使用了该头文件的每个C语言文件中定义静态变量,按照编译的步骤,在每个头文件中都会单独存在一个静态变量,从而会引起资源的浪费或者程序错误。