静态变量是一个非常重要的知识点,无论笔试面试,都是一个高频的考点!确实也十分重要,这里简单的总结一下,它C与C++中的作用!!以备后用!
静态变量的实现原理:
static变量在第一次调用函数时,static变量初始化。第二次,及以后调用函数,static变量不会初始化。static变量在编译时会被默认初始化为0。
#include <iostream>
using namespace std;
void fun(int i)
{
static int num=i;
int *p=#
cout<<num<<endl;
num++;
}
int main()
{
for(int i=10;i>0;i--)
fun(i);
system("pause");
return 0;
}
运行结果:
结论:如果是static修饰的变量,其中编译器会专门设置一个位为标志位,如果该变量第一次被初始化,则该位i被设置为1,初始值为0。当再次进入的时候,如果发现该标志位是1,则不再对该位进行初始化;由于其值的生命周期是整个程序,所以当我们调用它的时候,其值就为上一次我们修改过的值,而不是初始值。
变量的生命周期与作用域
静态变量属于静态存储方式,其存储空间为内存中的静态数据区(在 静态存储区内分配存储单元),该区域中的数据在整个程序的运行期间一直占用这些存储空间(在程序整个运行期间都不释放),也可以认为是其内存地址不变,直 到整个程序运行结束。
(相反,而auto自动变量,即动态局部变量,属于动态存储类别,占动态存储空间,函数调用结束后即释放)。
void show1()
{
if(1)
{
static int b=1 ;
//作用域就是所在的大括号,生命周期长;一直存在;
}
// printf("%d\n",b++); //不能使用;
}
静态变量虽在程序的整个执 行过程中始终存在,但是在它作用域之外不能使用。
#include <iostream>
using namespace std;
//虽然离开定义它的函数后不能使用,但如再次调用定义它的函数时,它又可继续使用,
//而且保存了前次被调用后留下的值。因此,当多次调用一个函数且要求在调用之间保留某些变量的值时,可考虑采用静态局部变量
void show()
{
static int a =10; a++; cout<<a<<endl;
}
int main()
{
show(); show(); //cout<<a<<endl;
//)静态局部变量的生存期虽然为整个源程序,但是其作用域仍与自动变量相同,
//即只能在定义该变量的函数内使用该变量。退出该函数后,尽管该变量还继续存在,但不能使用它。
system("pause");
return 0;
}
静态变量是在程序执行之前创建,并在程序的整个执行过程中一直存在。
所谓 静态存储方式是指在程序运行期间分配固定的存储空间的方式
变量的存储方式可分为:“静态存储”和“动态存储”两种。
静态存储变量通常是在变量定义时就分定存储单元并一直保持不变,直至整个程序结束。全局变量即属于此类存储方式。
动态存储变量是在程序执行过程中,使用它时才分配存储单元,使用完毕立即释放。
典型的例子是函数的形式参数,在函数定义时并不给行参分配存储单元,只是在函数被调用时,才予以分配,调用函数完毕立即释放。
C中作用域及生命周期 函数 文件 程序
static int b;
1.静态变量的作用域是变量定义时所在在的大括号,其他都不好使,没定义,但是该变量一直存在;
2.生命周期是整个程序;
3.静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。
把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。
把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。
因此static 这个说明符在不同的地方所起的作用是不同的。
C++中被static修饰的成员变量,
1.静态成员函数与非静态成员函数的根本区别是:
静态成员函数没有this指针,而非静态成员函数含有一个指向当前对象的this指针,隐藏了这么一个参数;
2.静态变量或函数在编译的时候就已经存在;静态变量必须在类外进行初始化;
3.大师言论“静态函数和静态变量是类的组成部分,而不是类对象的组成部分。可用“类名::静态变量名“的形式直接调用”。
4.静态函数里定义的变量是普通的,若想是静态的,必须加关键字static;
静态成员函数,内联函数,友元函数,构造函数,不能申明为虚函数!
对象:无名对象,常量对象,指针对象,实例对象;
实例如下:
#include <iostream>
using namespace std;
struct student
{
int num;
char c;
};
class aa
{
public:
static int num; //静态成员变量;申明类型,并未定义
static student stu[2]; //静态结构体变量;
int n;
aa()
{
//num=100; //静态变量必须在类外进行初始化,如果不放在类外,定义一个对象就会创建一份,重复定义,竞争资源;
}
static void show() //没有对象的那个this指针;所有对象指向一个,不确定this到底指向谁;
{
//只能是static成员属性;
cout<<num<<endl;
int a ;//静态函数定义的变量还是普通变量;静态变量一定要加static关键字;
//cout<<n<<endl; //对非静态成员N 的非法引用;
//普通成员属性在没有对象的时候是没有空间的,所以n是非法访问,
}
};
int aa::num=100; //静态变量需在类外初始化,num在类外,用作用域来声明;
student aa::stu[]={{1,'a'},{2,'b'}};
student aa::stu[2]={{1,'a'},{2,'b'}};
//静态结构体的两种初始化方式;
int main()
{
// aa a ;
// cout<<a.num<<endl; //a.num==aa::num 意义一样,可以采用对象直接调用,其实编译器是只认类型(aa)不认对象(a),只是通过a找到aa类型的;
cout<<aa::num<<endl; //静态变量在编译时就申请了空间;所以不需要创建对象也可以调用;
cout <<sizeof (aa)<<endl; //没有生成对象,所以大小是4;若没有int n,则为1(占位,实例化唯一)静态变量在编译的时候就分配了空间;
//sizsof(aa)表示用aa去定义变量,需要申请多大的空间;
aa b;
b.num++;
aa c; //不同的对象指向的是同一个空间;
//静态成员属性属于这个类,而不是属于某个对象,所有的对象共享这个静态成员;
cout<<c.num<<endl;//值改变了;
cout<<aa::show<<endl;//打印该函数入口地址;
aa::show(); //调用静态函数;
system("pause");
return 0;
}
本人愚钝,领悟至此,颇有感慨,与己共勉,陋文浅显,见者海涵。