static 是由最初的限制和持久过渡到后的共享。
C语言时代的static
在C语言中,只存在函数和变量。
A、函数和全局变量,一旦加上static关键字,就限制了其作用域为本文件有效。
B、局部变量,一旦加上static关键字,其生命其为整个应用程序。
C++语言时代的static
在C++语言中,除了向C语言兼容外,提供了类的支持,同样static在C语言的特性在C++同样有效。
C、类的static关键字,在C++的类中,static只能用于修饰数据成员和函数成员(不能修饰构造函数和析构函数),用于该类所具有的信息而不属具体某个对象.
D、<注意>如果在类的成员函数中定义了static局部变量,其值会在所有对象中共享!这一点不好!
C#语言时代的static
在C#语言中,基于类static访问特性和C++相似。同时,也有了一些改变。
E、在C#中,禁止了类成员函数中的局部变量用static修饰。
F、类的静态成员字段的初始化更加简单,可以直接在类定义中赋值。初始值设定是按照文本顺序执行,如果类中有静态字段而无静态构造函数,系统会自动生成,并先于静态构造函数执行。
G、类提供了static修饰构造函数。类的静态构造函数在给定应用程序域中至多执行一次:只有创建类的实例或者引用类的任何静态成员才激发静态构造函数
可见static从C-->C++是由简入繁。
C#作为一种全新的语言,他消除了C++语言的一些复杂性,全面支持面向对象。所以没有C语言的全局函数和全局变量。类成员函数内也不支持静态成员变量了。
下面用下事例代码,全面阐述以上内容

/**//////////////////////////////////////////////////////////////////////////////////////
//C语言事例A
//用来表示不能被其它文件访问的全局变量和函数。, 但为了限制全局变量/函数的作用域, 函数或变量前加static使得函数成为静态函数。但此处“static”的含义不是指存储方式,而是指对函数的作用域仅局限于本文件(所以又称内部函数)。注意此时, 对于外部(全局)变量, 不论是否有static限制, 它的存储区域都是在静态存储区, 生存期都是全局的. 此时的static只是起作用域限制作用, 限定作用域在本模块(文件)内部.
//使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名。
//c2.c
int g_i=0;
static int g_is=0;

int f1()


{
return 1;
}
static int f2()


{
return 2;
}
//c1.c
extern int g_i; //引用文件c3.h的全局变量
extern int g_is; //声明有一个外部全局变量g_is
extern int f1();
extern int f2();
#include <stdio.h>
void main()


{
printf("%d\n",g_i);
//printf("%d\n",g_is); //报错
printf("%d\n",f1());
//printf("%d\n",f2()); //报错,不能访问的函数.
}
//C语言事例B
//局部变通变量与局部静态变量的区别
//1. 存储空间分配不同
//auto类型分配在栈上, 属于动态存储类别, 占动态存储区空间, 函数调用结束后自动释放, 而static分配在静态存储区, 在程序整个运行期间都不释放. 两者之间的作用域相同, 但生存期不同.
//2. static局部变量在所处模块在初次运行时进行初始化工作, 且只操作一次
//3. 对于局部静态变量, 如果不赋初值, 编译期会自动赋初值0或空字符, 而auto类型的初值是不确定的.
//c3.c
#include <stdio.h>
void Print()


{
static int a=0;
int b=0;
a++;
b++;
printf("a = %d,b = %d \n",a,b);
}
void main()


{
for (int i=0; i<3; i++)
Print();
}
//会发现a的会记住上一次的值。具有不可重入性。

/**//////////////////////////////////////////////////////////////////////////////////////
//C++语言事例C
//很多时候需要将类看作一个整体,当这个整体的一些相关信息就可以用static来维护和管理
//c4.c
#include <iostream.h>

class Test


{
private:
int a;
static char creator[16];
public:
static char* const GetCreator()

{
//a = 1; //静态成员函数不能访问类的非静态字段
return creator;
}
};
char Test::creator[16]="这是Fung建的类!";

void main()


{
cout<<Test::GetCreator()<<endl;
}
//C++语言事例D
//尽量不要在类的成员函数中定义static变量,这可能导致程序混乱.
//c5.c
#include <iostream.h>

class Test


{
public:
void fun()

{
static int a=0;
a += 3;
cout<<a<<endl;
}
};

void main()


{
Test* t = new Test();
t->fun();
t->fun();
Test* k = new Test();
k->fun(); //这里第一输出就变成了9
}
//★静态数据成员可以成为成员函数的可选参数,而普通数据成员则不可以。
//c6.c
#include <iostream.h>

class Test


{
static int s;
int a;
public:
int fun(int i = s) //静态数据成员可以成为成员函数的可选参数

{
return i;
}
//int fun1(int i = a) //这个是当然不行了
//{
// return i;
//}
};
int Test::s = 5;

void main()


{
Test* t = new Test();
cout<<t->fun()<<endl;
}

/**//////////////////////////////////////////////////////////////////////////////////////
//C#语言事例
//(1)用于对静态字段、只读字段等的初始化。
//(2)添加static关键字,不能添加访问修饰符,因为静态构造函数都是私有的。
//(3)类的静态构造函数在给定应用程序域中至多执行一次:只有创建类的实例或者引用类的任何静态成员才激发静态构造函数
//(4)静态构造函数是不可继承的,而且不能被直接调用。
//(5)如果类中包含用来开始执行的 Main 方法,则该类的静态构造函数将在调用 Main 方法之前执行。
// 任何带有初始值设定项的静态字段,则在执行该类的静态构造函数时,先要按照文本顺序执行那些初始值设定项。
//(6)如果没有编写静态构造函数,而这时类中包含带有初始值设定的静态字段,那么编译器会自动生成默认的静态构造函数。
using System;
class Test


{

static void Main()
{
Console.WriteLine("{0} {1}", B.Y, A.X);
}

public static int F(string s)
{
Console.WriteLine(s);
return 1;
}
}
class A


{
public static int X = Test.F("Init A");
}
class B


{
public static int Y = Test.F("Init B");
}
//或者产生如下输出:
//Init A
//Init B
//1 1
//或者产生如下输出:
//Init B
//Init A
//1 1
//这是因为 X 的初始值设定项和 Y 的初始值设定项的执行顺序无法预先确定,上述两种顺序都有可能发生;
//唯一能够确定的是:它们一定会在对那些字段的引用之前发生。但是,下面的示例:
using System;
class Test


{

static void Main()
{
Console.WriteLine("{0} {1}", B.Y, A.X);
}

public static int F(string s)
{
Console.WriteLine(s);
return 1;
}
}
class A


{

static A()
{}
public static int X = Test.F("Init A");
}
class B


{

static B()
{}
public static int Y = Test.F("Init B");
}
//所产生的输出必然是:
//Init B
//Init A
//1 1
//这是因为关于何时执行静态构造函数的规则规定:
//B 的静态构造函数(以及 B 的静态字段初始值设定项)必须在 A 的静态构造函数和字段初始值设定项之前运行
