static解析

原创 2016年08月30日 15:25:16

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.


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

相关文章推荐

c++解析html并显示的static控件

  • 2013年04月26日 21:24
  • 65KB
  • 下载

Java进阶--static完全解析

前言现在深深的感觉到写一篇好的博客十分不容易,static关键字的考点在各种笔试面试中会经常遇到,在写这篇博客之前我也是大量的阅读了相关的文献,争取从全局上对static做一个分析,这里的全局包括JV...

全局和局部静态变量(static)解析

static声明主要特性是两点:生命周期和作用域。 我们决定使用静态局部变量还是静态全局变量所考虑的就是该变量是否需要一直存在,或者该变量是否应该被限制在某个作用域,例如某个函数或者某个源文件内。 ...

Java中的static关键字解析

Java中的static关键字解析   static关键字是很多朋友在编写代码和阅读代码时碰到的比较难以理解的一个关键字,也是各大公司的面试官喜欢在面试时问到的知识点之一。下面就先讲述一下stati...

Java中的static关键字解析

static在java中的应用
  • wjs08
  • wjs08
  • 2016年06月10日 13:00
  • 61

Java中static关键字解析以及类加载顺序例题

一.static关键字的用途 在《Java编程思想》P86页有这样一段话:   “static方法就是没有this的方法。在static方法内部不能调用非静态方法,反过来是可以的。而且可以...
  • xxk20
  • xxk20
  • 2016年03月17日 17:48
  • 587

Java常见笔试面试题目解析(一):final与static final变量(原生类型)的初始化方式

public class FinalOriginalTest { private final int a; private String name; public FinalOrigina...

C语言static关键字解析

1、概述   static 声明的变量在C语言中有两方面的特征:   1)、变量会被放在程序的全局存储区中,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是它与堆栈变量和堆变量的区别。 ...
  • wu_zf
  • wu_zf
  • 2011年12月13日 21:18
  • 6950

Java中的static关键字解析

先讲述一下static关键字的用法和平常容易误解的地方,最后列举了一些面试笔试中常见的关于static的考题。以下是本文的目录大纲:   一.static关键字的用途   二.static关键字的...

static关键字原理解析

C程序一直由下列部分组成:       1)正文段——CPU执行的机器指令部分;一个程序只有一个副本;只读,防止程序由于意外事故而修改自身指令;       2)初始化数据段(数据段)——在程序中...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:static解析
举报原因:
原因补充:

(最多只允许输入30个字)