static解析

static解析

面向过程程序设计中的static和面向对象程序设计中的static。前者应用于普通变量和函数,不涉及类(C及C++共有);后者主要说明static在类中的作用(C++独有)。

一、面向过程设计中的static

1、静态全局变量

1)在全局数据区分配内存;

2)未经初始化会被程序自动初始化为0(自动变量的值是随机的,除非它被显式初始化);

3)在声明它的整个文件都是可见的,而在文件之外是不可见的。故不能被其它文件所用;且避免与其它文件相同名字变量冲突。

注:一般程序的由new产生的动态数据存放在堆区,函数内部的自动变量存放在栈区。自动变量一般会随着函数的退出而释放空间,静态数据(即使是函数内部的静态局部变量)也存放在全局数据区。全局数据区的数据并不会因为函数的退出而释放空间。


eg1:

#include <iostream>

using std::cout;
using std::endl;

void fun();

//定义静态全局变量
static int n; 

int main(int argc, char* argv[])
{
	n = 20;
	cout << n << endl;
	fun();
	return 0;
}

void fun()
{
	n++;
	cout << n << endl;
}


eg2:

fun.cpp:

#include <iostream>

using std::cout;
using std::endl;

extern int n;

void fun() 
{
	n++;
	cout << n << endl;
}

main.cpp:

<p>#include<iostream></p><p> </p><p>usingstd::cout;</p><p>usingstd::endl;</p><p> </p><p>void fun();</p><p> </p><p>static int n;//定义静态全局变量</p><p> </p><p>int main(intargc, char* argv[]) </p><p>{</p><p>       n = 20;</p><p>       cout << n << endl;</p><p>       fun();</p><p>       return 0;</p><p>}</p>
在VS2015 Community下编译,出现如下编译错误信息

无法编译,编译错误如下:

1>------ 已启动全部重新生成: 项目: test, 配置: Debug Win32------

1>  main.cpp

1>  fun.cpp

1>  正在生成代码...

1>fun.obj :error LNK2001: 无法解析的外部符号 "intn" (?n@@3HA)

1>F:\Workspace\test\Debug\test.exe: fatal error LNK1120: 1 个无法解析的外部命令

========== 全部重新生成: 成功 0 个,失败 1 个,跳过 0 个 ==========

将static int n;更改为int n,进行编译,可以编译通过。


2、静态局部变量

它的值保存在全局数据区,而不是保存在栈中,每次的值保持到下一次调用,直到下次赋新值。即具有”记忆性”与生存期的”全局性”。
1)在全局数据区分配内存;
2)在程序执行到该对象的声明处时被首次初始化,如果没有显式初始化,会被程序自动初始化为0;以后进行函数调用不再初始化;
3)始终驻留在全局数据区,直到程序运行结束;但其作用域为局部作用域,当定义它的函数或语句块结束时,其作用域随之结束。

eg:

#include <iostream>

using std::cout;
using std::endl;

void fun();

int main(int argc, char* argv[]) 
{
	fun();
	fun();
	fun();
	return 0;
}

void fun()
{
	static int n = 10;
	cout << n << endl;
	n++;
}


3、静态函数

不能被其它文件所用,从而避免与其他相同函数名的文件冲突。

eg:

#include <iostream>

using std::cout;
using std::endl;

//声明静态函数
static void fun();

int main(int argc, char* argv[])
{
	fun();
}

//定义静态函数
void fun()
{  
	int n = 10;
	cout << n << endl;
}


 

二、面向过程设计中的static

1、静态数据成员

1)非静态数据成员,每个类对象都有自己的拷贝;而静态数据成员在程序中只有一份拷贝,只分配一次内存,由该类型的所有对象共享访问;

2)存储在全局数据区,故定义时要分配空间,而不能在类声明中定义;

3)和普通数据成员一样遵从public,protected,private访问规则;

4)主要用在各个对象都有相同的某项属性的时候;

5)避免不存在与程序中其它全局名字冲突的可能性;

6)实现信息隐藏;静态数据成员可以是private成员,而全局变量不能

初始化的格式为:

<数据类型><类名>::<静态数据成员名> = <值>

对于public的访问形式为:

<类对象名>.<静态数据成员名> 或 <类类型名>::<静态数据成员名>

eg:

#include <iostream>

using std::cout;
using std::endl;

class MyClass 
{
public:
	MyClass(int a, int b, int c);
	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 << "Sum = " << Sum << endl;
}

int main(int argc, char* argv[])
{
	MyClass M(1, 2, 3);
	M.GetSum();
	MyClass N(4, 5, 6);
	N.GetSum();
	return 0;
}


2、静态成员函数

1)出现在类体外的函数定义不能指定关键字static;
2)静态成员之间可以相互访问,包括静态成员函数访问静态数据成员和访问静态成员函数;
3)非静态成员函数可以任意地访问静态成员函数和静态数据成员;
4)静态成员函数不能访问非静态成员函数和非静态数据成员;
由于没有this指针的额外开销,因此静态成员函数与类的全局函数相比速度上会有少许的增长;
调用静态成员函数,可以用成员访问操作符(.)和(->)为一个类的对象或指向类对象的指针调用静态成员函数,也可以直接使用如下格式:
<类名>::<静态成员函数名>(<参数表>)
eg:

#include <iostream>

using std::cout;
using std::endl;

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;

}

int main(int argc, char* argv[]) 
{
	MyClass M(1, 2, 3);
	M.GetSum();
	MyClass N(4, 5, 6);
	N.GetSum();
	MyClass::GetSum();
	return 0;
}


参考文献

[1]  C语言中,关键字static的作用.  http://blog.sina.com.cn/s/blog_4cfafddd0100fq92.html.

[2] C/C++中static关键字作用总结.  http://www.cnblogs.com/biyeymyhjob/archive/2012/07/19/2598815.html.

[3] C中static的常见作用.  http://blog.chinaunix.net/uid-21411227-id-1826981.html.

[4] static在C和C++中的用法和区别.  http://www.cnblogs.com/10jschen/archive/2012/09/22/2698137.html.


注:为了便于自己学习,无心侵权,尽可能将所引用的文章列举出来;有些文章的内容可能会与原作重复度较高,还请谅解。如作者举报,愿意删除此文。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值