<1> 栈 : 由编译器自动分配内存,存放函数的参数值,局部变量等,操作方式类似于数据结构中的栈。
<2> 堆 : 由程序员自己分配,若程序不释放,一般在程序结束时由os释放。 比如说new 之类的,类似于数据结构中的链表<3> 全局区: 全局变量和静态变量都是存储在这一块的,包括静态局部变量和静态全局变量。初始化过的放在一块,没有初始化的放在另一块。程序结束后由系统释放。
<4> 文字常量区,常量字符串存放的区域,程序结束后由系统释放。
一种是保存在栈区, char name5[20] = "fengkewei";
或 char name1[] = "fengkewei";
一种保存在文字常量区, 即 char *name = "fengkewei";
一种保存在全局区(静态区)(下次有机会再说。。。)
最后一种保存在堆区,即用malloc, alloc, realloc 分配内存分配的区域,可由程序员自身分配和释放
<5> 代码区 :存放函数的二进制代码
2 static在面向过程中的作用
<1> 静态全局变量
在全局变量前加上staic,和全局变量的区别是:
1> 全局变量在可以其他文件中使用,加上extern就可以
2> 静态全局变量 作用域是在当前文件,在其他文件中可以定义相同的名称的变量不会冲突
<2> 静态局部变量
1>静态局部变量在执行到该对象的声明出时,首次被初始化,以后的函数调用不会再进行初始化
2>
静态局部变量一般在声明处初始化,如果没有初始化,会被程序自动初始化为0
3》依然存放在全局区,知道程序运行结束,由os收回
<3> 静态函数:
在函数的返回类型前面加上static 。与普通函数的区别是,它只能在声明的文件中使用,在其他文件中不能使用,在其他文件中有相同的函数名,不会冲突
static void fn();
3 static 在面向对象中作用
<1> 静态数据成员
1>公共(public)静态数据成员可被类的外部访问,保护(protected)或私有(private)静态数据成员只可被类的内部访问。
2> 访问方式
方式一:<类对象名>.<静态数据成员名>
方式二:<类类型名>::<静态数据成员名>
3> 静态数据成员的初始化方式:
<数据类型><类名>::<静态数据成员名>=<值>
4>与全局变量的区别
(一)静态数据成员没有进入程序的全局名字空间,因此不存在与程序中其它全局名字冲突的可能性;
(二)可以实现信息隐藏。静态数据成员可以是private成员,而全局变量不能;
5> 特点:
(一)对于非静态数据成员,每个类对象都有自己的拷贝。而静态数据成员被当作是类的成员。无论这个类的对象被定义 了多少个,静态数据成员在程序中也只有一份拷贝,由该类型的所有对象共享访问。也就是说,静态数据成员是该 类的所有对象所共有的。对该类的多个对象来说,静态数据成员只分配一次内存,供所有对象共 用。所以,静态数据成员 的值对每个对象都是一样的,它的值可以更新;
(二)静态数据成员存储在全局数据区。静态数据成员定义时要分配空间,所以不能在类声明中定义。语句int Myclass::Sum=0;是定义静态数据成员;
(三)静态数据成员和普通数据成员一样遵从public,protected,private访问规则;
(四)因为静态数据成员在全局数据区分配内存,属于本类的所有对象共享,,即在没有产生类的实例时,我们就可以操 作它;
(五)在静态成员函数和非静态成员函数中都可以使用
<2> 静态成员函数
在.h文件中定义的时候加上static,但是在实现的实现的时候前面并不需要加static关键字。
与普通函数相比,静态成员函数由于不是与任何的对象相联系,因此它不具有this指 针。无法访问属于类对象的非静态数据 成员,也无法访问非静态成员函数,它只能调用其余的静态成员函数或者静态成员变量。
主要特点如下:
1> 在类外实现的时候不加static关键字。
2> 静态成员函数之间可以相互访问,包括静态成员函数和静态成员变量,
3> 静态成员函数因为不具有this指针,因此不能访问非静态成员和非静态成员函数
4> 非静态成员函数可以访问静态成员函数和静态成员变量
5> 类类型名>::<静态成员函数>
4 关于静态成员函数和静态成员变量的实例
#include <iostream.h>
class Myclass
{public:
Myclass(int a,int b,int c);
static void GetSum();/声明静态成员函数
private:
int a,b,c;
static int Sum;//声明静态数据成员
};
int Myclass::Sum=0;//定义并初始化静态数据成员
Myclass::Myclass(int a,int b,int c)
{ this->a=a;
this->b=b;
this->c=c;
Sum+=a+b+c; //非静态成员函数可以访问静态数据成员
}
void Myclass::GetSum() //静态成员函数的实现
{// cout<<a<<endl; //错误代码,a是非静态数据成员
cout<<"Sum="<<Sum<<endl;
}
void main()
{ Myclass M(1,2,3);
M.GetSum();
Myclass N(4,5,6);
N.GetSum();
Myclass::GetSum();
}
5 注意:
静态数据成员是静态存储的,所以必须对它进行初始化。
静态成员初始化与一般数据成员初始化不同:
初始化在类体外进行,而前面不加static,以免与一般静态变量或对象相混淆;
初始化时不加该成员的访问权限控制符private,public等;
初始化时使用作用域运算符来标明它所属类;
所以我们得出静态数据成员初始化的格式:
6 补充1:
7 补充2:
4.★静态数据成员的类型可以是所属类的类型,而普通数据成员则不可以。普通数据成员的只能声明为 所属类类型的 指针或引用。举例如下:
class base{
public :
static base _object1;//正确,静态数据成员
base _object2;//错误
base *pObject;//正确,指针
base &mObject;//正确,引用
};
8 补充3:
静态成员函数没有什么太多好讲的。
1.静态成员函数的地址可用普通函数指针储存,而普通成员函数地址需要用 类成员函数指针来储存。举例如下:
class base{
static int func1();
int func2();
};
int (*pf1)()=&base::func1;//普通的函数指针
int (base::*pf2)()=&base::func2;//成员函数指针
2.静态成员函数不可以调用类的非静态成员。因为静态成员函数不含this指针,包括普通成员函数和普通成员变量。
3.静态成员函数不可以同时声明为 virtual、const、volatile函数。举例如下:
class base{
virtual static void func1();//错误
static void func2() const;//错误
static void func3() volatile;//错误
};