静态变量和非静态变量的区别

本文详细介绍了静态变量和非静态变量之间的区别,包括内存分配、生命周期、作用域、调用方式及共享方式等,并解释了静态变量仅初始化一次的原因。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

静态变量和非静态变量的区别:
非静态变量可以有局部变量和全局变量
静态变量实际上就是指在内存中的地址是静态不变的。
1、内存分配:局部变量存储在堆区或者栈区,静态变量和全局变量一样存储在全局区,
静态变量在应用程序初始化时,就存在于内存当中,直到它所在的类的程序运行结束时才消亡;
而非静态变量需要被实例化后才会分配内存。
2、生命周期:静态变量和全局变量存在于整个应用程序存在的周期,而非静态变量(指局部变量)
则取决于类实例化 的存在周期。
3、作用域:静态变量作用域是文件,而非静态(全局)变量的作用域是整个应用程序,局部变量
的作用域是相应的代码块。
4、调用方式:在类中静态变量可以通过类和实例调用,非静态变量只能通过实例调用。
5、共享方式:静态变量是全局变量,类中所用实例共享同一静态变量,即一个类实例中的变量改变其它实例中的该静态
变量跟着变,非静态变量(局部)只属于当前实例,不共享。




另外为什么静态变量只会被初始化一次呢:
童鞋们在学习C++的时候,往往只是按照书本上的原文去强行记忆各种特性,比方说,静态变量只初始化一次。你心中一定在默念:一定要记住,static只会初始化一次云云,希望自己能够记住。告诉你,你为什么总是记不住,因为你没有正真理解静态变量的原理, 所以下面我就来告诉大家它的原理,直接上代码:
[code=C/C++]
#include "stdafx.h"


int _tmain(int argc, _TCHAR* argv[])
{
int initNum = 3;
for (int i=5; i > 0; --i)
{
static int n1 = initNum;
n1++;
printf("%d\n", n1);
}


getchar();
return 0;
}
[/code]
输出结果:
4
5
6
7
8


在这里我们可以看到虽然代码循环了5次,静态变量n1确实只初始化了一次。那么为什么呢?继续上代码,相信大家就会明白些许了。
[code=C/C++]
int _tmain(int argc, _TCHAR* argv[])
{
int initNum = 3;
for (int i=5; i > 0; --i)
{
static int n1 = initNum;


//我们在这里了两句代码
int* p = &n1;
p++;
*p = 0;
//end


n1++;
printf("%d\n", n1);
}


getchar();
return 0;
}
[/code]
输出结果:
4
4
4
4
4


这次,静态变量居然跟随着5次循环也初始化了5次。你一定非常诧异,其实我们不难推断,其实静态变量就是通过静态变量后面的一个32位内存位来做记录,
以标识这个静态变量是否已经初始化。而我们的p++;*p = 0;却每次都将这个值赋值为0,所以程序就一直认为n1一直没有被初始化过,并每次都初始化一次。
看一下内存,就更明了了:
0x00E8716C  03 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 b0 e7 1e 6a 00 00 00
这里的内存地址就是静态变量n1的地址,值是3,后面还有一个1,你看到了吗,这个就是程序用来记录该静态变量是否初始化的标识位啦。现在你一定明白
原理了,并且能轻松记住静态变量的特性了吧?
童鞋们还可以试一下,多个静态变量时,标识位的表示形式,以深入学习(透露一下,每一位标识一个静态变量的初始化状态)。

以上代码有一点需要说明:代码中之所以要用int initNum = 3;而不是直接用static int n1 = 3;是因为如果给静态变量直接赋值一个常量的话,编译器会进行优化,
导致程序在一启动时,就初始化好了,不便于我们观察静态变量内存上的改变。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值