① static在C和java中的区别。
static声明的变量在C语言中有两方面的特征:
1)、变量会被放在程序的全局存储区中,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是它与堆栈变量和堆变量的区别。
2)、变量用static告知编译器,自己仅仅在变量的作用范围内可见。这一点是它与全局变量的区别。
Tips:
A.若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度;
B.若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度;
C.设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题;
D.如果我们需要一个可重入的函数,那么,我们一定要避免函数中使用static变量(这样的函数被称为:带“内部存储器”功能的的函数)
E.函数中必须要使用static变量情况:比如当某函数的返回值为指针类型时,则必须是static的局部变量的地址作为返回值,若为auto类型,则返回为错指针。
函数前加static使得函数成为静态函数。但此处“static”的含义不是指存储方式,而是指对函数的作用域仅局限于本文件(所以又称内部函数)。使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名。
扩展分析:术语static有着不寻常的历史.起初,在C中引入关键字static是为了表示退出一个块后仍然存在的局部变量。随后,static
在C中有了第二种含义:用来表示不能被其它文件访问的全局变量和函数。为了避免引入新的关键字,所以仍使用static关键字来表示这第二种含义。最后,
C++重用了这个关键字,并赋予它与前面不同的第三种含义:表示属于一个类而不是属于此类的任何特定对象的变量和函数(与Java中此关键字的含义相
同)。
关键字static的作用是什么?
这个简单的问题很少有人能回答完全。在C语言中,关键字static有三个明显的作用:
1在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。
2 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。
3在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用。
大多数应试者能正确回答第一部分,一部分能正确回答第二部分,同是很少的人能懂得第三部分。这是一个应试者的严重的缺点,因为他显然不懂得本地化数据和代码范围的好处和重要性
int testStatic()
{
int x=1;
x++;
return x;
}
main()
{
int i;
for(i=0;i<5;i++)
printf("%d\n",testStatic());
getch();
}
==》2 2 2 2 2
int testStatic()
{
static int x=1;
x++;
return x;
}
main()
{
int i;
for(i=0;i<5;i++)
printf("%d\n",testStatic());
getch();
}
==》2 3 4 5 6
转载源地址为
http://blog.21ic.com/user1/2992/archives/2007/37456.html
② Java中的关键字static和final的作用
final
根据程序上下文环境,Java关键字final有“这是无法改变的”或者“终态的”含义,它可以修饰非抽象类、非抽象类成员方法和变量。你可能出于两种理解而需要阻止改变:设计或效率。
final类不能被继承,没有子类,final类中的方法默认是final的。
final方法不能被子类的方法覆盖,但可以被继承。
final成员变量表示常量,只能被赋值一次,赋值后值不再改变。
final不能用于修饰构造方法。
注意:父类的private成员方法是不能被子类方法覆盖的,因此private类型的方法默认是final类型的。
1、final类
final类不能被继承,因此final类的成员方法没有机会被覆盖
,默认都是final的。在设计类时候,如果这个类不需要有子类,类的实现细节不允许改变,并且确信这个类不会载被扩展,那么就设计为final类。
2、final方法
如果一个类不允许其子类覆盖某个方法,则可以把这个方法声明为final方法。
使用final方法的原因有二:
第一、把方法锁定,防止任何继承类修改它的意义和实现。
第二、高效。编译器在遇到调用final方法时候会转入内嵌机制,大大提高执行效率。
例如:
publicclassTest1{
publicstaticvoidmain(String[]args){
//TODO自动生成方法存根
}
publicvoidf1(){
System.out.println("f1");
}
//无法被子类覆盖的方法
publicfinalvoidf2(){
System.out.println("f2");
}
publicvoidf3(){
System.out.println("f3");
}
privatevoidf4(){
System.out.println("f4");
}
}
publicclassTest2extendsTest1{
publicvoidf1(){
System.out.println("Test1父类方法f1被覆盖!");
}
publicstaticvoidmain(String[]args){
Test2t=newTest2();
t.f1();
t.f2();//调用从父类继承过来的final方法
t.f3();//调用从父类继承过来的方法
//t.f4();//调用失败,无法从父类继承获得
}
}
3、final变量(常量)
用final修饰的成员变量表示常量,值一旦给定就无法改变!
final修饰的变量有三种:静态变量、实例变量和局部变量,分别表示三种类型的常量。
从下面的例子中可以看出,一旦给final变量初值后,值就不能再改变了。
另外,final变量定义的时候,可以先声明,而不给初值,这中变量也称为final空白,无论什么情况,编译器都确保空白final在使用之前必须被初始化。但是,final空白在final关键字final的使用上提供了更大的灵活性,为此,一个类中的final数据成员就可以实现依对象而有所不同,却有保持其恒定不变的特征。
packageorg.leimin;
publicclassTest3{
privatefinalStringS="final实例变量S";
privatefinalintA=100;
publicfinalintB=90;
publicstaticfinalintC=80;
privatestaticfinalintD=70;
publicfinalintE;//final空白,必须在初始化对象的时候赋初值
publicTest3(intx){
E=x;
}
/**
*@paramargs
*/
publicstaticvoidmain(String[]args){
Test3t=newTest3(2);
//t.A=101;//出错,final变量的值一旦给定就无法改变
//t.B=91;//出错,final变量的值一旦给定就无法改变
//t.C=81;//出错,final变量的值一旦给定就无法改变
//t.D=71;//出错,final变量的值一旦给定就无法改变
System.out.println(t.A);
System.out.println(t.B);
System.out.println(t.C);//不推荐用对象方式访问静态字段
System.out.println(t.D);//不推荐用对象方式访问静态字段
System.out.println(Test3.C);
System.out.println(Test3.D);
//System.out.println(Test3.E);//出错,因为E为final空白,依据不同对象值有所不同.
System.out.println(t.E);
Test3t1=newTest3(3);
System.out.println(t1.E);//final空白变量E依据对象的不同而不同
}
privatevoidtest(){
System.out.println(newTest3(1).A);
System.out.println(Test3.C);
System.out.println(Test3.D);
}
publicvoidtest2(){
finalinta;//final空白,在需要的时候才赋值
finalintb=4;//局部常量--final用于局部变量的情形
finalintc;//final空白,一直没有给赋值.
a=3;
//a=4;出错,已经给赋过值了.
//b=2;出错,已经给赋过值了.
}
}
4、final参数
当函数参数为final类型时,你可以读取使用该参数,但是无法改变该参数的值。
publicclassTest4{
publicstaticvoidmain(String[]args){
newTest4().f1(2);
}
publicvoidf1(finalinti){
//i++;//i是final类型的,值不允许改变的.
System.out.print(i);
}
}
二、static
static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念。
被static修饰的成员变量和成员方法独立于该类的任何对象。也就是说,它不依赖类特定的实例,被类的所有实例共享。只要这个类被加载,Java虚拟机就能根据类名在运行时数据区的方法区内定找到他们。因此,static对象可以在它的任何对象创建之前访问,无需引用任何对象。
用public修饰的static成员变量和成员方法本质是全局变量和全局方法,当声明它类的对象市,不生成static变量的副本,而是类的所有实例共享同一个static变量。
static变量前可以有private修饰,表示这个变量可以在类的静态代码块中,或者类的其他静态成员方法中使用(当然也可以在非静态成员方法中使用--废话),但是不能在其他类中通过类名来直接引用,这一点很重要。实际上你需要搞明白,private是访问权限限定,static表示不要实例化就可以使用,这样就容易理解多了。static前面加上其它访问权限关键字的效果也以此类推。
static修饰的成员变量和成员方法习惯上称为静态变量和静态方法,可以直接通过类名来访问,访问语法为:
类名.静态方法名(参数列表...)
类名.静态变量名
用static修饰的代码块表示静态代码块,当Java虚拟机(JVM)加载类时,就会执行该代码块(用处非常大,呵呵)。
1、static变量
按照是否静态的对类成员变量进行分类可分两种:一种是被static修饰的变量,叫静态变量或类变量;另一种是没有被static修饰的变量,叫实例变量。两者的区别是:
对于静态变量在内存中只有一个拷贝(节省内存),JVM只为静态分配一次内存,在加载类的过程中完成静态变量的内存分配,可用类名直接访问(方便),当然也可以通过对象来访问(但是这是不推荐的)。
对于实例变量,没创建一个实例,就会为实例变量分配一次内存,实例变量可以在内存中有多个拷贝,互不影响(灵活)。
2、静态方法
静态方法可以直接通过类名调用,任何的实例也都可以调用,因此静态方法中不能用this和super关键字,不能直接访问所属类的实例变量和实例方法(就是不带static的成员变量和成员成员方法),只能访问所属类的静态成员变量和成员方法。因为实例成员与特定的对象关联!这个需要去理解,想明白其中的道理,不是记忆!!!
因为static方法独立于任何实例,因此static方法必须被实现,而不能是抽象的abstract。
3、static代码块
static代码块也叫静态代码块,是在类中独立于类成员的static语句块,可以有多个,位置可以随便放,它不在任何的方法体内,JVM加载类时会执行这些静态的代码块,如果static代码块有多个,JVM将按照它们在类中出现的先后顺序依次执行它们,每个代码块只会被执行一次。例如:
publicclassTest5{
privatestaticinta;
privateintb;
static{
Test5.a=3;
System.out.println(a);
Test5t=newTest5();
t.f();
t.b=1000;
System.out.println(t.b);
}
static{
Test5.a=4;
System.out.println(a);
}
publicstaticvoidmain(String[]args){
//TODO自动生成方法存根
}
static{
Test5.a=5;
System.out.println(a);
}
publicvoidf(){
System.out.println("hhahhahah");
}
}
运行结果:
3
hhahhahah
1000
4
5
利用静态代码块可以对一些static变量进行赋值,最后再看一眼这些例子,都一个static的main方法,这样JVM在运行main方法的时候可以直接调用而不用创建实例。
4、static和final一块用表示什么
static final用来修饰成员变量和成员方法,可简单理解为“全局常量”!
对于变量,表示一旦给值就不可修改,并且通过类名可以访问。
对于方法,表示不可覆盖,并且可以通过类名直接访问。
特别要注意一个问题:
对于被static和final修饰过的实例常量,实例本身不能再改变了,但对于一些容器类型(比如,ArrayList、HashMap)的实例变量,不可以改变容器变量本身,但可以修改容器中存放的对象,这一点在编程中用到很多。
也许说了这么多,反倒把你搞晕了,还是看个例子吧:
publicclassTestStaticFinal{
="aaa";
=null;
privatefinalStringstrFinalVar=null;
=0;
=newInteger(8);
privatestaticfinalArrayList<String>alStaticFinalVar=newArrayList<String>();
privatevoidtest(){
System.out.println("-------------值处理前---------- ");
System.out.println("strStaticFinalVar="+strStaticFinalVar+" ");
System.out.println("strStaticVar="+strStaticVar+" ");
System.out.println("strFinalVar="+strFinalVar+" ");
System.out.println("intStaticFinalVar="+intStaticFinalVar+" ");
System.out.println("integerStaticFinalVar="+integerStaticFinalVar+" ");
System.out.println("alStaticFinalVar="+alStaticFinalVar+" ");
//strStaticFinalVar="哈哈哈哈";//错误,final表示终态,不可以改变变量本身.
strStaticVar="哈哈哈哈";//正确,static表示类变量,值可以改变.
//strFinalVar="呵呵呵呵";//错误,final表示终态,在定义的时候就要初值(哪怕给个null),一旦给定后就不可再更改。
//intStaticFinalVar=2;//错误,final表示终态,在定义的时候就要初值(哪怕给个null),一旦给定后就不可再更改。
//integerStaticFinalVar=newInteger(8);//错误,final表示终态,在定义的时候就要初值(哪怕给个null),一旦给定后就不可再更改。
alStaticFinalVar.add("aaa");//正确,容器变量本身没有变化,但存放内容发生了变化。这个规则是非常常用的,有很多用途。
alStaticFinalVar.add("bbb");//正确,容器变量本身没有变化,但存放内容发生了变化。这个规则是非常常用的,有很多用途。
System.out.println("-------------值处理后---------- ");
System.out.println("strStaticFinalVar="+strStaticFinalVar+" ");
System.out.println("strStaticVar="+strStaticVar+" ");
System.out.println("strFinalVar="+strFinalVar+" ");
System.out.println("intStaticFinalVar="+intStaticFinalVar+" ");
System.out.println("integerStaticFinalVar="+integerStaticFinalVar+" ");
System.out.println("alStaticFinalVar="+alStaticFinalVar+" ");
}
publicstaticvoidmain(Stringargs[]){
newTestStaticFinal().test();
}
}
看了上面这个例子,就清楚很多了,但必须明白:通过static final修饰的容器类型变量中所“装”的对象是可改变的。这是和一般基本类型和类类型变量差别很大的地方。
③ java中static的用法
static可以修饰变量(属性)、方法、代码块和内部类
static属性:属于这个类所有,即由该类创建的所有对象共享同一个static属性。可以对象创建后通过对象名.属性名和类名.属性名两种方式来访问。也可以在没有创建任何对象之前通过类名.属性名的方式来访问。
static方法:也可以通过对象名.方法名和类名.方法名两种方式来访问
static代码块:当类被第一次使用时(可能是调用static属性和方法,或者创建其对象)执行静态代码块,且只被执行一次,主要作用是实现static属性的初始化。
static内部类:属于整个外部类,而不是属于外部类的每个对象。不能访问外部类的非静态成员(变量或者方法),.可以访问外部类的静态成员
④ java中static是什么意思能不能通俗的讲下,让我这个菜鸟好理解一点
static英文是静态的意思,所以它在java中也是这么用的,是一个修饰词,在定义数据前面加上它是指这个数据是静态不变的,在方法明加上它是指这个方法是静态的。一般就是这些用处
⑤ 在java中什么时候使用static ,static是不是等于全局变量
static是静态变量,并不是常量,全局变量是相对于局部变量来说的,全局变量可以改变,在程序的任何地方都可以读取和修改,而局部变量只能在语句块内作用,超出作用范围就失效了.
静态变量(static)是相对自动变量(auto)等而言的,一旦声明为静态变量,在编译时刻开始永远存在,不受作用域范围约束,但是如果是局部静态变量,则此静态变量只能在局部作用域内使用,超出范围不能使用,但是它确实还占用内存,还存在.自动变量就是一般的变量,在C语言中auto关键字可以省略.
int d;//全局变量
static int a;//静态全局变量
void func()
{
int c;//局部变量
}
main()
{
static int d;//静态局部变量
int b;//局部变量
}
⑥ c语言中static说明是什么意思
在C语言中,static关键字的作用如下:
1、在修饰变量的时,static修饰的静态局部变量只执行一次,而且延长了局部变量的生命周期,直到程序运行结束以后才释放。
2、static修饰全局变量的时,这个全局变量只能在本文件中访问,不能在其它文件中访问,即便是extern外部声明也不可以。
3、static修饰一个函数,则这个函数的只能在本文件中调用,不能被其他文件调用。Static修饰的局部变量存放在全局数据区的静态变量区。
(6)cjavastatic扩展阅读:
static关键字在C语言、C++、java中的作用有着相似之处,但也存在差异:
一、C++的static用法:
1、面向过程程序设计中的static和面向对象程序设计中的static。前者应用于普通变量和函数,不涉及类;后者主要说明static在类中的作用。
2、在类中,static可以用来修饰静态数据成员和静态成员方法
静态数据成员
(1)静态数据成员可以实现多个对象之间的数据共享,它是类的所有对象的共享成员,它在内存中只占一份空间,如果改变它的值,则各对象中这个数据成员的值都被改变。
(2)静态数据成员是在程序开始运行时被分配空间,到程序结束之后才释放,只要类中指定了静态数据成员,即使不定义对象,也会为静态数据成员分配空间。
(3)静态数据成员既可以通过对象名引用,也可以通过类名引用。
静态成员函数
(1)静态成员函数和静态数据成员一样,他们都属于类的静态成员,而不是对象成员。
(2)非静态成员函数有this指针,而静态成员函数没有this指针。
(3)静态成员函数主要用来方位静态数据成员而不能访问非静态成员。
二、java的static用法:
1、声明为static的变量称为静态变量或类变量。可以直接通过类名引用静态变量,也可以通过实例名来引用静态变量,但最好采用前者,因为后者容易混淆静态变量和一般变量。
2、声明为static的方法称为静态方法或类方法。静态方法可以直接调用静态方法,访问静态变量,但是不能直接访问实例变量和实例方法。静态方法中不能使用this关键字,因为静态方法不属于任何一个实例。
参考资料来源:网络-static(计算机高级语言)
⑦ JAVA 中的关键字static
static
C++的static有两种用法:面向过程程序设计中的static和面向对象程序设计中的static。前者应用于普通变量和函数,不涉及类;后者主要说明static在类中的作用。
一、面向过程设计中的static
1、静态全局变量
在全局变量前,加上关键字static,该变量就被定义成为一个静态全局变量。我们先举一个静态全局变量的例子,如下:
//Example 1#include <iostream.h>void fn();static int n; //定义静态全局变量void main(){ n=20; cout<<n<<endl; fn();}void fn(){ n++; cout<<n<<endl;}
静态全局变量有以下特点:
该变量在全局数据区分配内存;
未经初始化的静态全局变量会被程序自动初始化为0(自动变量的值是随机的,除非它被显式初始化);
静态全局变量在声明它的整个文件都是可见的,而在文件之外是不可见的;
静态变量都在全局数据区分配内存,包括后面将要提到的静态局部变量。对于一个完整的程序,在内存中的分布情况如下图:
代码区
全局数据区
堆区
栈区
一般程序的由new产生的动态数据存放在堆区,函数内部的自动变量存放在栈区。自动变量一般会随着函数的退出而释放空间,静态数据(即使是函数内部的静态局部变量)也存放在全局数据区。全局数据区的数据并不会因为函数的退出而释放空间。细心的读者可能会发现,Example 1中的代码中将
static int n; //定义静态全局变量
改为
int n; //定义全局变量
程序照样正常运行。
的确,定义全局变量就可以实现变量在文件中的共享,但定义静态全局变量还有以下好处:
静态全局变量不能被其它文件所用;
其它文件中可以定义相同名字的变量,不会发生冲突;
您可以将上述示例代码改为如下:
//Example 2//File1#include <iostream.h>void fn();static int n; //定义静态全局变量void main(){ n=20; cout<<n<<endl; fn();}//File2#include <iostream.h>extern int n;void fn(){ n++; cout<<n<<endl;}
编译并运行Example 2,您就会发现上述代码可以分别通过编译,但运行时出现错误。 试着将
static int n; //定义静态全局变量
改为
int n; //定义全局变量
再次编译运行程序,细心体会全局变量和静态全局变量的区别。
2、静态局部变量
在局部变量前,加上关键字static,该变量就被定义成为一个静态局部变量。
我们先举一个静态局部变量的例子,如下:
//Example 3#include <iostream.h>void fn();void main(){ fn(); fn(); fn();}void fn(){ static n=10; cout<<n<<endl; n++;}
通常,在函数体内定义了一个变量,每当程序运行到该语句时都会给该局部变量分配栈内存。但随着程序退出函数体,系统就会收回栈内存,局部变量也相应失效。
但有时候我们需要在两次调用之间对变量的值进行保存。通常的想法是定义一个全局变量来实现。但这样一来,变量已经不再属于函数本身了,不再仅受函数的控制,给程序的维护带来不便。
静态局部变量正好可以解决这个问题。静态局部变量保存在全局数据区,而不是保存在栈中,每次的值保持到下一次调用,直到下次赋新值。
静态局部变量有以下特点:
该变量在全局数据区分配内存;
静态局部变量在程序执行到该对象的声明处时被首次初始化,即以后的函数调用不再进行初始化;
静态局部变量一般在声明处初始化,如果没有显式初始化,会被程序自动初始化为0;
它始终驻留在全局数据区,直到程序运行结束。但其作用域为局部作用域,当定义它的函数或语句块结束时,其作用域随之结束;
3、静态函数
在函数的返回类型前加上static关键字,函数即被定义为静态函数。静态函数与普通函数不同,它只能在声明它的文件当中可见,不能被其它文件使用。
静态函数的例子:
//Example 4#include <iostream.h>static void fn();//声明静态函数void main(){ fn();}void fn()//定义静态函数{ int n=10; cout<<n<<endl;}
定义静态函数的好处:
静态函数不能被其它文件所用;
其它文件中可以定义相同名字的函数,不会发生冲突;
二、面向对象的static关键字(类中的static关键字)
1、静态数据成员
在类内数据成员的声明前加上关键字static,该数据成员就是类内的静态数据成员。先举一个静态数据成员的例子。
//Example 5#include <iostream.h>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;}void main(){ Myclass M(1,2,3); M.GetSum(); Myclass N(4,5,6); N.GetSum(); M.GetSum();}
可以看出,静态数据成员有以下特点:
对于非静态数据成员,每个类对象都有自己的拷贝。而静态数据成员被当作是类的成员。无论这个类的对象被定义了多少个,静态数据成员在程序中也只有一份拷贝,由该类型的所有对象共享访问。也就是说,静态数据成员是该类的所有对象所共有的。对该类的多个对象来说,静态数据成员只分配一次内存,供所有对象共用。所以,静态数据成员的值对每个对象都是一样的,它的值可以更新;
静态数据成员存储在全局数据区。静态数据成员定义时要分配空间,所以不能在类声明中定义。在Example 5中,语句int Myclass::Sum=0;是定义静态数据成员;
静态数据成员和普通数据成员一样遵从public,protected,private访问规则;
因为静态数据成员在全局数据区分配内存,属于本类的所有对象共享,所以,它不属于特定的类对象,在没有产生类对象时其作用域就可见,即在没有产生类的实例时,我们就可以操作它;
静态数据成员初始化与一般数据成员初始化不同。静态数据成员初始化的格式为:
<数据类型><类名>::<静态数据成员名>=<值>
类的静态数据成员有两种访问形式:
<类对象名>.<静态数据成员名> 或 <类类型名>::<静态数据成员名>
如果静态数据成员的访问权限允许的话(即public的成员),可在程序中,按上述格式来引用静态数据成员 ;
静态数据成员主要用在各个对象都有相同的某项属性的时候。比如对于一个存款类,每个实例的利息都是相同的。所以,应该把利息设为存款类的静态数据成员。这有两个好处,第一,不管定义多少个存款类对象,利息数据成员都共享分配在全局数据区的内存,所以节省存储空间。第二,一旦利息需要改变时,只要改变一次,则所有存款类对象的利息全改变过来了;
同全局变量相比,使用静态数据成员有两个优势:
静态数据成员没有进入程序的全局名字空间,因此不存在与程序中其它全局名字冲突的可能性;
可以实现信息隐藏。静态数据成员可以是private成员,而全局变量不能;
2、静态成员函数
与静态数据成员一样,我们也可以创建一个静态成员函数,它为类的全部服务而不是为某一个类的具体对象服务。静态成员函数与静态数据成员一样,都是类的内部 实现,属于类定义的一部分。普通的成员函数一般都隐含了一个this指针,this指针指向类的对象本身,因为普通成员函数总是具体的属于某个类的具体对象的。通常情况下,this 是缺省的。如函数fn()实际上是this->fn()。但是与普通函数相比,静态成员函数由于不是与任何的对象相联系,因此它不具有this指针。从这个意义上讲,它无法访问属于类对象的非静态数据成员,也无法访问非静态成员函数,它只能调用其余的静态成员函数。下面举个静态成员函数的例子。
//Example 6#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();}
关于静态成员函数,可以总结为以下几点:
出现在类体外的函数定义不能指定关键字static;
静态成员之间可以相互访问,包括静态成员函数访问静态数据成员和访问静态成员函数;
非静态成员函数可以任意地访问静态成员函数和静态数据成员;
静态成员函数不能访问非静态成员函数和非静态数据成员;
由于没有this指针的额外开销,因此静态成员函数与类的全局函数相比速度上会有少许的增长;
调用静态成员函数,可以用成员访问操作符(.)和(->)为一个类的对象或指向类对象的指针调用静态成员函数,也可以直接使用如下格式:
<类名>::<静态成员函数名>(<参数表>)
调用类的静态成员函数。
===============================================================================================
static静态变量声明符。 在声明它的程序块,子程序块或函数内部有效,值保持,在整个程序期间分配存储器空间,编译器默认值0。
是C++中很常用的修饰符,它被用来控制变量的存储方式和可见性。
2、为什么要引入static?
函数内部定义的变量,在程序执行到它的定义处时,编译器为它在栈上分配空间,大家知道,函数在栈上分配的空间在此函数执行结束时会释放掉,这样就产生了一个问题: 如果想将函数中此变量的值保存至下一次调用时,如何实现?最容易想到的方法是定义一个全局的变量,但定义为一个全局变量有许多缺点,最明显的缺点是破坏了此变量的访问范围(使得在此函数中定义的变量,不仅仅受此函数控制)。
3、什么时候用static?
需要一个数据对象为整个类而非某个对象服务,同时又力求不破坏类的封装性,即要求此成员隐藏在类的内部,对外不可见。
4、static的内部机制:
静态数据成员要在程序一开始运行时就必须存在。因为函数在程序运行中被调用,所以静态数据成员不能在任何函数内分配空间和初始化。
这样,它的空间分配有三个可能的地方,一是作为类的外部接口的头文件,那里有类声明;二是类定义的内部实现,那里有类的成员函数定义;三是应用程序的main()函数前的全局数据声明和定义处。
静态数据成员要实际地分配空间,故不能在类的声明中定义(只能声明数据成员)。类声明只声明一个类的“尺寸和规格”,并不进行实际的内存分配,所以在类声明中写成定义是错误的。它也不能在头文件中类声明的外部定义,因为那会造成在多个使用该类的源文件中,对其重复定义。
static被引入以告知编译器,将变量存储在程序的静态存储区而非栈上空间,静态
数据成员按定义出现的先后顺序依次初始化,注意静态成员嵌套时,要保证所嵌套的成员已经初始化了。消除时的顺序是初始化的反顺序。
5、static的优势:
可以节省内存,因为它是所有对象所公有的,因此,对多个对象来说,静态数据成员只存储一处,供所有对象共用。静态数据成员的值对每个对象都是一样,但它的值是可以更新的。只要对静态数据成员的值更新一次,保证所有对象存取更新后的相同的值,这样可以提高时间效率。
6、引用静态数据成员时,采用如下格式:
<类名>::<静态成员名>
如果静态数据成员的访问权限允许的话(即public的成员),可在程序中,按上述格式
来引用静态数据成员。
7、注意事项:
(1)类的静态成员函数是属于整个类而非类的对象,所以它没有this指针,这就导致
了它仅能访问类的静态数据和静态成员函数。
(2)不能将静态成员函数定义为虚函数。
(3)由于静态成员声明于类中,操作于其外,所以对其取地址操作,就多少有些特殊
,变量地址是指向其数据类型的指针 ,函数地址类型是一个“nonmember函数指针”。
(4)由于静态成员函数没有this指针,所以就差不多等同于nonmember函数,结果就
产生了一个意想不到的好处:成为一个callback函数,使得我们得以将C++和C-based X W
indow系统结合,同时也成功的应用于线程函数身上。
(5)static并没有增加程序的时空开销,相反她还缩短了子类对父类静态成员的访问
时间,节省了子类的内存空间。
(6)静态数据成员在<定义或说明>时前面加关键字static。
(7)静态数据成员是静态存储的,所以必须对它进行初始化。
(8)静态成员初始化与一般数据成员初始化不同:
初始化在类体外进行,而前面不加static,以免与一般静态变量或对象相混淆;
初始化时不加该成员的访问权限控制符private,public等;
初始化时使用作用域运算符来标明它所属类;
所以我们得出静态数据成员初始化的格式:
<数据类型><类名>::<静态数据成员名>=<值>
(9)为了防止父类的影响,可以在子类定义一个与父类相同的静态变量,以屏蔽父类的影响。这里有一点需要注意:我们说静态成员为父类和子类共享,但我们有重复定义了静态成员,这会不会引起错误呢?不会,我们的编译器采用了一种绝妙的手法:name-mangling 用以生成唯一的标志。
编辑本段static 函数
内部函数和外部函数
当一个源程序由多个源文件组成时,C语言根据函数能否被其它源文件中的函数调用,将函数分为内部函数和外部函数。
1 内部函数(又称静态函数)
如果在一个源文件中定义的函数,只能被本文件中的函数调用,而不能被同一程序其它文件中的函数调用,这种函数称为内部函数。
定义一个内部函数,只需在函数类型前再加一个“static”关键字即可,如下所示:
static 函数类型 函数名(函数参数表)
{……}
关键字“static”,译成中文就是“静态的”,所以内部函数又称静态函数。但此处“static”的含义不是指存储方式,而是指对函数的作用域仅局限于本文件。
使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名,因为同名也没有关系。
2 外部函数
外部函数的定义:在定义函数时,如果没有加关键字“static”,或冠以关键字“extern”,表示此函数是外部函数:
[extern] 函数类型 函数名(函数参数表)
{……}
调用外部函数时,需要对其进行说明:
[extern] 函数类型 函数名(参数类型表)[,函数名2(参数类型表2)……];
[案例]外部函数应用。
(1)文件mainf.c
main()
{ extern void input(…),process(…),output(…);
input(…); process(…); output(…);
}
(2)文件subf1.c
……
extern void input(……) /*定义外部函数*/
{……}
(3)文件subf2.c
……
extern void process(……) /*定义外部 函数*/
{……}
(4)文件subf3.c
……
extern void output(……) /*定义外部函数*/
{……}
⑧ java静态方法(方法前冠以static)和实例方法(未冠以static)的区别
静态方法(方法前冠以static)和实例方法(前面未冠以static)的区别
调用静态方法或说类方法时,可以使用类名做前缀,也可以使用某一个具体的对象名;通常使用类名。
非static的方法是属于某个对象的方法,而static的方法是属于整个类的,不被任何一个对象单独拥有;
由于static方法是属于整个类的,所以它不能操纵和处理属于某个对象的成员变量,而只能处理属于整个类的成员变量,也即,static方法只能处理static域或静态方法。实例方法可以访问实例域, 静态域或静态方法, 记住都行。
声明为static的方法有以下几条限制: 1.它们仅能调用其他的static方法。
2.它们只能访问static数据。
3.它们不能以任何方式引用this或super(关键 字super与继承有关,在下一章中描述)。
static method Have No this Reference
All instance methods have a hidden parameter—this
So,
Static method can’t access instance methods and fields; it can only
invoke other static class
members.It can access class members only.
instance can use static method.
Instance methods:
If a method is declared without the static modifier keyword,
that method is known as an instance method. Instance methods
are associated with objects – not classes.
It can access either instance or class members.
本章源码
class StaticExa {
static int a = 4;
static int b = 9;
static void call() {
System.out.println("a = " + a);//静态方法可以访问静态属性
}
}
public class Test {
static int c = 43;
public static void main(String args[]) {
/*刚运行到这一步时,debug观察,StaticExa.a的值就等于42,Test.c的值就等于43,
说明系统在我们的程序一开始时,就会给所有的类变量赋值。如果是对象参考, 就是null,
见photoshop的例子*/
。。。。。。。。。。。。。。。。详情网上找“马克-to-win”,参考他的网站或他的网络空间:java第2章的内容
⑨ JAVA中的static
Java是个面向对象编程的语言,一般而言,方法需要通过实例对象来调用。但是有一些方法不需要实例对象(或者说没有这样的对象)来调用,那么就可以在方式前面加上static修饰符,表示这个方法是静态方法,不需要实例对象就可以调用。
例如String类的valueOf(int arg0)方法,作用是得到整数参数arg0的字符串表示,不需要创建出一个String类的实例对象来调用这个方法,所以它是static的。
如果你学过C/C++,你就会知道C/C++程序有一个入口,就是main()函数。电脑执行C/C++程序的时候就以main()函数作为入口,首先执行main()函数。Java也是类似,JVM首先调用main()方法。这个时候还没有什么实例对象呢,所以必须把main()方法声明为static,以便JVM调用。
如果是在类中变量前加static修饰的话,就是另外一个意思了。例如“人”这个类,有一个成员变量叫做“姓名”。现在new一个“人”的实例对象叫做“张三”,再new一个“人”的实例对象叫做“李四”。张三、李四自然有各自的“姓名”,它们的“姓名”成员变量在内存当中各自占一块存储单元,互不干扰。但是,如果在“人”这个类的“姓名”成员变量前加上static修饰的话,那么就变成了类变量。还是new出来“张三”“李四”,这次张三、李四的“姓名”在内存中就不是各自独立的存储区域了,而是共用一个存储区域。所有“人”的实例对象的“姓名”其实都是指的那一个存储单元。无论创建10个“人”对象还是100个“人”对象,它们的“姓名”指向的都是内存中的那一个存储单元。如果被更改了,实际上所有的对象的“姓名”都会改了,因为它们引用的都是内存中的那一个存储单元。就好像这个变量是属于类而不是属于实例对象的。
静态方法因为不需要实例对象就可以调用,所以当然其中也不可以使用实例对象变量。原因很简单啊,调用静态方法的时候怎么知道实例对象有没有创建、实例对象变量有没有初始化过呢。还是拿String类的valueOf()方法举例。假设valueOf()方法里面调用了String的一个实例对象str的某个成员变量。
那么以下这行代码
String.valueOf(10);
执行的时候,如何确定此时str对象就一定被创建出来并且成员变量都初始化过有值了呢?
⑩ JAVA! static什么作用
static是静态修饰符,static可以用来区分成员变量、方法是属于类本身还是属于类实例化后的对象。有static修饰的成员属于类本身,没有static修饰的成员属于类的实例。
static静态变量是属于类的,只有一份存储空间,是类之间共享的,牵一发而动全身,一处变,处处变。实例变量属于实例对象,创建几次对象,就有几份的成员变量(拷贝)。
(10)cjavastatic扩展阅读
static的使用
示例:
classa{
publicstatic$aa=1;
publicstaticfunctionaa(){
self::$aa+=1;
echoself::$aa;
}
}
classb{
publicfunctionbb(){
a::aa();
}
}
classc{
publicfunctioncc(){
a::aa();
}
}
$bbb=newb();
$ccc=newc();
$bbb->bb();
echo'*******************';
$ccc->cc();