关于static

C语言部分(谭浩强C语言程序设计)

首先要了解什么是全局变量

全局变量又叫外部变量:在函数外定义,可为本文件所有函数公用,也叫外部变量.

有效范围:从定义变量的位置开始到本源文件结束,及有extern说明的其他的源文件

demo

#include <stdio.h>

int a = 10; //全局变量(定义在函数外部)


int subNum(int,int);

int getNumA();


int main(int argc, const char * argv[]) {

    // insert code here...

    int b = 20;

    int c = subNum(a,b);

    int d = getNumA();

    printf("a = %d, b = %d, c = %d\n", d, b, c);

//    printf("subNum Func e = %d", e); //全局变量e是在函数main的后面定义的,所以int e = 3;后面的代码中可以使用,前面不可以使用,会报错

    return 0;

}


int e = 3; //全局变量(定义在函数外部)


int subNum(int a, int b)

{

    printf("subNum Func e = %d\n", e);

    return a + b;

}


int getNumA()

{

    printf("getNumA Func e = %d\n", e);

    return a;

}

接下来,我们再创建一个.c文件来印证全局变量可以在有extern说明的其他源文件

ReferenceGlobalVar.c文件

#include <stdio.h>

extern int e;


int main()

{

    printf("ReferenceGlobalVar e = %d\n",e); //打印结果 ReferenceGlobalVar e = 3

    return 0;

}

全局变量的使用,增加了函数间数据联系的渠道,同一文件中的所有函数都能引用全局变量的值,当某函数改变了全局变量的值时,便会影响其他的函数.


使用注意:

1>习惯上,全局变量名的第一个字母用大写(所以上面定义的全局变量int a=10;int e=3;应该改成大写的int A = 10; int E = 3;才比较规范,这里就不再修改了)

2>使用全局变量可以减少函数实参和形参的个数

3>不必要时不要使用全局变量,因为1)全局变量在程序执行的全过程都占用存储单元2)不利于程序的移植.程序的可读性变差

4>全局变量与局部变量重名时,在函数内部将屏蔽全局变量

再重新创建一个.c文件来验证第四点GlobalVarRename.c

#include <stdio.h>

int A = 10;


int main()

{

    printf("befor for A = %d\n", A);

    for(int A = 0; A < 5; A++)

    {

        printf("for A = %d ", A);

    }

    printf("\nafter for A = %d\n", A);

    return 0;

}

打印结果:

befor for A = 10

for A = 0 for A = 1 for A = 2 for A = 3 for A = 4 

after for A = 10

所以for循环中用的是临时定义的变量A初始值为0,而for循环前后使用的都是全局变量A初始化值为10


接下来我们了解一下变量的分类:

按数据类型:整形,实型,字符型 (int,float,char)

按作用域:全局变量,局部变量 (函数内部/外部定义)

存储方式:

静态存储:程序运行期间分配固定的存储空间 

动态存储:程序运行期间根据需要动态分配存储空间 


变量的生存周期:

静态变量:从程序开始执行到程序结束

动态变量:从包含该变量定义的函数开始执行至函数执行结束


内存用户区:

静态存储区: 全局变量,局部静态变量

动态存储区: 形参变量,局部动态变量,函数调用现场保护和返回地址等

auto变量

函数内部无static声明的局部变量均为动态存储类别,被分配在动态区

存储类别为自动时,声明符auto可省;自动变量被分配到动态区,未赋初值时,其值未定义,每次调用重新赋值

auto int b,c=3;  == int b,c=3;


用static声明局部变量

若希望函数调用结束后,局部变量的值保留,则指定该变量为静态局部变量,用static对变量加以声明

(局部静态变量具有可继承性)


#include <stdio.h>


void func();


int main()

{

    func();

    func();

    func();

    return 0;

}


void func()

{

    static int i = 0;

    i++;

    printf("i = %d ", i);

}

输出结果:

i = 1 i = 2 i = 3


对静态局部变量的说明:

1)分配在静态区,程序运行结束释放存储单元

2)赋初值一次未赋初值时为0,前次保留结果

int main()

{

    static int i;

    printf("i = %d\n", i);

    return 0;

}

输出结果:

i = 0

3)局部动态变量若未赋初值,其值不确定,局部静态变量未赋初值,其值为0或’\0’字符变量

int main()

{

    static int i;

    static char j;

    int h;

    printf("i = %d, j = %c, h = %d\n", i, j, h);

    return 0;

}

输出结果:

i = 0, j =  ,h = 1606422582


4)静态局部变量在函数调用结束后虽存在,但其他函数不能引用它

void func();


int main()

{

    func();

    func();

    func();

//    printf("i = %d", i);

    func();

    return 0;

}


void func()

{

    static int i = 0;

    i++;

    printf("i = %d ", i);

}

main函数引用静态局部变量i就会报错


使用局部静态变量的场合

1)需要保留上一次调用结束时的值

2)初始化后变量只被引用而不改变其值,则用静态局部变量较方便,以免每次调用时重新赋值,但会一直占用内存浪费系统资源


C++中关键字使用

静态成员的提出是为了解决数据共享的问题.在类中,静态成员可以实现多个对象之间的数据共享,并且使用静态数据成员还不会破坏隐藏性的原则,即保证了安全性.因此,静态成员是类的所有对象中共享的成员,而不是某个对象的成员.

使用静态数据成员可以节省内存,因为它是所有对象所公有的,因此,对多个对象来说,静态数据成员只存储一处,供所有对象共用。静态数据成员的值对每个对象都是一样,但它的值是可以更新的。只要对静态数据成员的值更新一次,保证所有对象存取更新后的相同的值,这样可以提高时间效率。


静态数据成员的使用方法和注意事项如下:

1)静态数据成员在定义或说明时前面加关键字static。
2)静态成员初始化与一般数据成员初始化不同。静态数据成员初始化的格式如下:
    <数据类型><类名>::<静态数据成员名>=<值>

class A

{

public:

A();

~A();

private:

static int i;

};

.cpp文件中

int A::i = 0;

A::A(){ A::i = 10; }

A::~A(){}

这表明:
(1) 初始化在类体外进行,而前面不加static,以免与一般静态变量或对象相混淆。

(2) 初始化时不加该成员的访问权限控制符private,public等。

(3) 初始化时使用作用域运算符来标明它所属类,因此,静态数据成员是类的成员,而不是对象的成员。

3、静态数据成员是静态存储的,它使静态生存期,必须对他进行初始化

4、引用静态数据成员时,采用如下格式:
<类名>::<静态成员名>
如果静态数据成员的访问权限允许的话(即public的成员),可在程序中,按上述格式来引用静态数据成员。

类中static成员函数
静态成员函数
静态成员函数和静态数据成员一样,他们都属于类的静态成员,他们都不是对象成员。因此对静态成员的引用不需要用对象名。

在静态成员函数的实现中不能直接引用类中说明的非静态成员,可以引用类中说明的静态成员。如果静态成员函数中要引用非静态成员时,可通过对象来引用。

读者可以自行分析其结果。从中可看出,调用静态成员函数使用如下格式:
   <类名>::<静态成员函数名>(<参数表>);

class B

{

public:

B();

~B();

static void HelloWorld();

private:

static int i;

int j;

};

.cpp文件中

int B::j = 10;

B::B(){}

B::~B(){}

void B::HelloWorld()

{

i++;

print("i = %d", i);

//不能直接引用j,会报错

}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
静态成员和实例成员是面向对象编程中的概念。 实例成员是指每个类的实例(对象)拥有的成员,它们与特定的对象实例相关联。每个对象都有自己的实例成员副本,它们在不同的对象之间是相互独立的。实例成员可以是字段、属性、方法或事件。 静态成员是属于类本身的成员,而不是属于类的实例(对象)的成员。静态成员被所有类的实例共享,它们只有一个副本在内存中存在。静态成员可以是静态字段、静态属性、静态方法或静态事件。 区别: 1. 内存分配:实例成员在每个对象实例中都有自己的内存分配,而静态成员只在内存中分配一次。 2. 访问方式:实例成员只能通过对象实例来访问,而静态成员可以通过类名直接访问,不需要创建对象实例。 3. 生命周期:实例成员的生命周期与对象实例相关联,当对象销毁时,实例成员也会被销毁。而静态成员的生命周期与类相关联,它们在应用程序运行期间一直存在,直到应用程序结束。 使用场景: - 当一个成员需要被多个对象共享时,可以将其定义为静态成员,例如记录类的实例数量。 - 当一个成员与对象的状态无关时,可以将其定义为静态成员,例如工具类中的方法。 - 当一个成员需要访问静态成员时,必须将其定义为静态成员,例如静态方法中只能访问静态成员。 总之,实例成员与对象实例相关联,而静态成员与类相关联。它们在内存分配、访问方式和生命周期等方面有所区别。根据实际需求选择使用哪种类型的成员。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值