C/C++/Java static 对比

之前对static的作用一直是一知半解,对于静态没有很好的理解,面试的时候问到static的作用也没有答好,于是特意学习了一下并记录下来,希望对其他困惑于此的同学有所帮助。

C

C的static有三种用途。C++的static用法包括了C的,因此先说C。

1. 静态局部变量

于函数内部修饰变量。
首先回顾一下C/C++的内存分配:

  1. 全局数据区 (data area):存放全局变量,静态数据和常量
  2. 代码区(code area):存放代码
  3. 栈 (stack):存放为运行函数而分配的局部变量、函数参数、返回数据、返回地址等
  4. 堆 (heap):余下的空间都是堆,一般手动分配,如malloc、new等

静态局部变量就存放于全局数据区。
程序第一次运行到该变量的声明处时初始化,之后即使再调用该函数也不会被再初始化。
如果声明处没有显式初始化,它将被初始化为0。(一般的局部变量在声明时不会强制初始化)
它始终保留在全局数据区直到程序结束,而局部变量在栈区,函数结束后就会释放占用的内存。

与全局变量的区别:全局变量不属于函数,不利于代码维护。虽然静态局部变量在全局数据区,但它只能被它所在的函数调用。

2. 静态全局变量

定义在函数体外,用于修饰全局变量,表示该变量仅在本文件可见。
如果不使用static修饰全局变量,其他文件可以使用extern获取该值。其他文件也可以定义相同的变量名而不冲突。
它在这里起到了文件隔离的作用。

3. 静态函数

静态函数与静态全局变量类似,静态函数不能被其他文件所用。其它文件可以定义相同名字的函数,不会冲突。

C++

除了以上三种,C++还有额外的两种用法:

1. 静态数据成员

用于修饰类 (class)的数据成员,这些成员叫静态成员。每个类有一份静态成员数据,而普通数据是每个实例 (instance)都有。因此静态数据成员也叫类变量,普通数据成员也叫实例变量。
静态数据被分配到全局数据区中,即使创建的类对象全部被摧毁,这些数据依然保留。与静态局部变量类似,静态数据成员也只被初始化一次。静态数据成员定义时要分配空间,所以不能在类声明中定义。

2. 静态成员函数

在类函数定义前加上static使它变成一个静态函数成员,可以用类名::函数名进行访问。
特点:

  1. 静态成员之间可以互相访问,包括静态成员函数访问静态数据成员和静态函数访问静态函数。
  2. 非静态成员函数可以任意访问静态成员函数和静态数据成员。
  3. 反过来不行,即静态成员函数不能访问非静态成员函数与非静态数据成员。
  4. 调用静态成员函数可以使用成员访问操作符(.)/(->),也可以用类名::函数名

Java

Java中的static与C/C++十分相似,但叫法不同。

1. 静态字段(类字段)

被标记为static的字段,每个类只持有一个。
例如:

class Employee
{
	private static int nextID = 1;
	private int id;
	...
}

每个Employee对象都有一个id,但所有的Employee对象共享一个nextID字段。
注意:即使没有Employee对象,静态字段也存在。它属于类,不属于任何一个实例。

2. 静态常量

静态常量使你不需要通过实例就可以访问到类中的常量。例如:

public class Math
{
	...
	public static final double PI = 3.1415926;
	...
}

在程序中可以使用Math.PI来访问该常量。如果没有static,PI就成了Math的实例字段,每个实例都持有一个PI副本,必须通过实例访问PI。这显然不是我们想要的。

3. 静态方法

与C++一样,静态方法指不在对象上执行的方法。如Math类的pow方法。静态方法是没有this参数的方法。
以下两种情况可以使用静态方法:

  • 方法不需要访问对象状态,因为它需要的所有参数都通过显示参数提供
  • 方法只需要访问类的静态字段

参考文章: C/C++中 static关键字.原博有代码辅助理解
Java参考的Core Java Volume I

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值