Static 最详细的解释(针对c++)

本文详细介绍了C与C++中static关键字的两种用法:面向过程和面向对象。在面向过程中,static用于全局和局部变量,限制其作用域并提供内存管理。在面向对象中,static用于静态数据成员和静态成员函数,实现类级别的共享和访问控制。静态数据成员为所有对象共享,静态成员函数不依赖于特定对象,且两者都不能访问非静态成员。

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

一、定义

C与C++#的static有两种用法: 面向过程程序设计中的static和面向对象程序设计中的static。前者应用于普通变量和函数,不涉及类;后者主要说明static在类中的作用。

二、面向过程

一、静态全局变量
在全局变量前,加上关键字static,该变量就被定义成为一个静态全局变量。如:
执行结果:20 和 21
在这里插入图片描述
特点:
1、变量在全局数据区分配内存
2、未经初始化的静态全局变量会被程序自动初始化为0(在函数体内声明的自动变量的值是随机的,除非它被显式初始化,而在函数体外被声明的自动变量也会被初始化为0)
3、静态全局变量在声明它的整个文件都是可见的,而在文件之外是不可见的
4、静态变量都在全局数据区分配内存,包括后面将要提到的静态局部变量
注意:全局变量和全局静态变量的区别
1)全局变量是不显视用static修饰的全局变量,全局变量默认是有外部链接性的,作用域是整个工程,在一个文件内定义的全局变量,在另一个文件中,通过extern 全局变量名的声明,就可以使用全局变量。
2)全局静态变量是显式用static修饰的全局变量,作用域是声明此变量所在的文件,其他的文件即使用extern声明也不能使用。
二、静态局部变量
在局部变量前,加上关键字static,该变量就被定义成为一个静态局部变量。如:
执行结果:21 、 22 、 23
在这里插入图片描述
特点
1、变量在全局数据区分配内存
2、静态局部变量在程序执行到该对象的声明处时被首次初始化,即以后的函数调用不再进行初始化
3、静态局部变量一般在声明处初始化,如果没有显式初始化,会被程序自动初始化为0
4、它始终驻留在全局数据区,直到程序运行结束。但其作用域为局部作用域,当定义它的函数或语句块结束时,其作用域随之结束

三、面向对象(类中的static关键字)

一、静态数据成员
在类内数据成员的声明前加上关键字static,该数据成员就是类内的静态数据成员。如:
执行结果:6 、 21 、 21在这里插入图片描述
特点
1、对于非静态数据成员,每个类对象都有自己的拷贝。而静态数据成员被当作是类的成员。无论这个类的对象被定义了多少个,静态数据成员在程序中也只有一份拷贝,由该类型的所有对象共享访问。也就是说,静态数据成员是该类的所有对象所共有的。对该类的多个对象来说,静态数据成员只分配一次内存,供所有对象共用。所以,静态数据成员的值对每个对象都是一样的,它的值可以更新
2、静态数据成员存储在全局数据区。静态数据成员定义时要分配空间,所以不能在类声明中定义。在例子中,语句int Myclass::Sum=0;是定义静态数据成员
3、静态数据成员和普通数据成员一样遵从public,protected,private访问规则
4、静态数据成员初始化与一般数据成员初始化不同。静态数据成员初始化的格式为:
<数据类型><类名>::<静态数据成员名>=<值>
类的静态数据成员有两种访问形式:
<类对象名>.<静态数据成员名> 或 <类类型名>::<静态数据成员名>
如果静态数据成员的访问权限允许的话(即public的成员),可在程序中,按上述格式来引用静态数据成员 ;
静态数据成员主要用在各个对象都有相同的某项属性的时候。比如对于一个存款类,每个实例的利息都是相同的。所以,应该把利息设为存款类的静态数据成员。这 有两个好处,第一,不管定义多少个存款类对象,利息数据成员都共享分配在全局数据区的内存,所以节省存储空间。第二,一旦利息需要改变时,只要改变一次, 则所有存款类对象的利息全改变过来了;
同全局变量相比,使用静态数据成员有两个优势:
a.静态数据成员没有进入程序的全局名字空间,因此不存在与程序中其它全局名字冲突的可能性;
b.可以实现信息隐藏。静态数据成员可以是private成员,而全局变量不能;
二、静态成员函数
与静态数据成员一样,我们也可以创建一个静态成员函数,它为类的全部服务而不是为某一个类的具体对象服务。静态成员函数与静态数据成员一样,都是类的内部 实现,属于类定义的一部分。普通的成员函数一般都隐含了一个this指针,this指针指向类的对象本身,因为普通成员函数总是具体的属于某个类的具体对象的。通常情况下,this 是缺省的。如函数fn()实际上是this->fn()。但是与普通函数相比,静态成员函数由于不是与任何的对象相联系,因此它不具有this指 针。从这个意义上讲,它无法访问属于类对象的非静态数据成员,也无法访问非静态成员函数,它只能调用其余的静态成员函数。如:
执行结果: 6、 21 、 21在这里插入图片描述
特点
1、出现在类体外的函数定义不能指定关键字static
2、静态成员之间可以相互访问,包括静态成员函数访问静态数据成员和访问静态成员函数
3、非静态成员函数可以任意地访问静态成员函数和静态数据成员
4、静态成员函数不能访问非静态成员函数和非静态数据成员
5、由于没有this指针的额外开销,因此静态成员函数与类的全局函数相比速度上会有少许的增长
6、调用静态成员函数,可以用成员访问操作符(.)和(->)为一个类的对象或指向类对象的指针调用静态成员函数,也可以直接使用如下格式:
<;类名>::<;静态成员函数名>;(<;参数表>;

<think>首先,用户的问题是关于C++中静态存储区的详细解释。用户询问了静态存储区的作用和工作原理。我需要基于提供的引用信息来回答,确保回答真实可靠。 回顾引用内容: -引用[1]:区分静态存储区和常量存储区,静态存储区存放全局变量和静态变量,常量存储区存放常量。-引用[2]:静态存储区用于存储全局变量、静态变量(包括全局和局部静态)和常量,生命周期贯穿整个程序。-引用[3]:全局/静态存储区存放全局变量和静态变量,没有区分初始化和未初始化。 -引用[4]:堆区、栈区和静态存储区的区别,静态存储区生命周期长,直到程序结束。用户的问题聚焦在静态存储区的作用和工作原理上。我需要结构化回答:1.**作用**:解释静态存储区在C++中的作用。2.**工作原理**:描述它如何工作,包括内存分配、生命周期等。 3. **与其他内存区域的区别**:如栈、堆、常量存储区,以突出其特性。 确保回答清晰、逐步解决: -先定义静态存储区。 -然后解释其作用。-接着详述工作原理。 -后总结或对比。使用中文回答,并遵守LaTeX格式: -行内数学表达式用$...$。-独立公式用$$...$$(但这里可能不需要数学公式)。 -在回答中引用段落时,末尾添加引用标识,如[^1]。生成相关问题:-在回答后,添加§§相关问题§§部分,列出2-3个相关问题。 用户上一次的问题可能涉及内存分配,但当前问题直接针对静态存储区。所以,专注于静态存储区。 结构化回答:1. **引言**:简要介绍静态存储区。 2. **作用**:列出主要作用。3.**工作原理**:解释分配、初始化、生命周期。 4. **区别**:对比栈和堆。 5. **总结**。 引用内容整合: -从引用[2]:静态存储区存储全局变量、静态变量和常量。 -从引用[3]:在C++中,全局和静态变量共享同一区域。-从引用[4]:生命周期长,与程序共存。注意:引用[1]提到常量存储区是特殊的,可能不同。但在引用[2]中,常量也被包括在静态存储区。我需要澄清:通常,常量存储区可能被视为静态存储区的一部分或相邻区域。 在C++中:-静态存储区主要存放全局变量和静态变量。 -常量存储区存放常量,如字符串常量,可能位于只读部分。 -引用[1]区分了它们,但引用[2]将它们一起讨论。为了准确,我应该说明静态存储区包括全局/静态变量,而常量可能单独处理。 基于标准C++: -静态存储区:用于静态存储期变量,包括全局变量、静态局部变量、静态成员变量。-常量存储区:用于常量,是只读的,可能位于代码段或类似区域。在回答中,澄清这一点。 生成相关问题:-例如:1.静态存储区中的变量如何初始化?2.静态存储区与栈或堆在性能上有什么差异?3.在C++中如何管理静态存储区的内存?确保回答真实可靠:基于引用和一般知识。</think>### C++静态存储区的作用和工作原理详解 在C++中,内存被划分为多个区域,包括栈、堆、自由存储区、全局/静态存储区和常量存储区。静态存储区是程序内存中的一个固定区域,专门用于存储具有静态存储期的变量。下面我将逐步解释其作用和工作原理,确保回答基于可靠的引用信息。 #### 1. **静态存储区的作用** 静态存储区的主要作用是存储那些在程序整个生命周期内都需要存在的变量,确保它们的内存分配和初始化在程序启动时完成,并在程序结束时释放。具体作用包括: - **存储全局变量和静态变量**:这包括全局变量(定义在任何函数之外的变量)、静态局部变量(在函数内部用`static`关键字声明的变量)和静态类成员变量(类中用`static`修饰的成员)。这些变量在程序运行期间保持持久性,不会因函数调用或退出而销毁[^2][^3]。 - **提供数据持久性**:静态存储区中的变量只被初始化一次(在程序启动时),之后的值在多次函数调用间保持不变。例如,一个静态局部变量在函数首次调用时初始化,后续调用会复用其值。 - **优化内存管理**:由于变量内存固定分配,无需动态申请和释放,减少了运行时开销,适合存储频繁访问的全局数据或配置信息[^4]。 需要注意的是,静态存储区与常量存储区(用于存放常量,如字符串常量)有区别:常量存储区是只读的,数据固化在可执行文件中,不占用运行时内存;而静态存储区是可读写的,位于内存空间,存储变量值[^1][^2]。 #### 2. **静态存储区的工作原理** 静态存储区的工作原理涉及内存分配、初始化和生命周期管理。以下是详细机制: - **内存分配时机**:在程序启动时(`main`函数执行前),操作系统或C++运行时环境会为静态存储区分配固定的内存空间。这块内存大小在编译期确定,基于程序中所有全局和静态变量的总大小[^2][^4]。 - **初始化过程**: - 变量在静态存储区中按声明顺序初始化。对于基本类型(如`int`, `float`),如果未显式初始化,则默认为零值(如`0`或`nullptr`);对于类对象,调用其构造函数[^3]。 - 初始化只发生一次。例如: ```cpp void func() { static int count = 0; // 首次调用时初始化,后续调用保留值 count++; } ``` 这里,`count`在第一次调用`func()`时初始化为0,之后每次调用递增,值持久保存。 - **生命周期**:静态存储区变量的生命周期从程序启动开始,到程序结束(`main`函数退出或`exit()`调用)时释放。内存由系统自动回收,开发者无需手动管理[^2][^4]。 - **内存布局**:在C++中,全局变量和静态变量共享同一块内存区域(不再区分初始化和未初始化区域)。这块区域位于进程地址空间的.data段(已初始化变量)或.bss段(未初始化变量,但默认置零),确保高效访问[^3]。 #### 3. **与其他内存区域的对比** 为了更清晰理解静态存储区,以下是其与栈和堆的关键区别: - **与栈的对比**:栈用于存储局部变量和函数调用上下文,生命周期短暂(随函数退出自动释放)。而静态存储区生命周期长,适合持久数据。例如: - 栈变量:`int x = 10;`(在函数内定义,退出时销毁)。 - 静态存储区变量:`static int y = 20;`(程序结束时销毁)[^4]。 - **与堆的对比**:堆用于动态内存分配(如`new`/`delete`),生命周期由开发者控制,但可能引发内存泄漏。静态存储区无需手动管理,但内存固定不可调整大小[^4]。 **总结**:静态存储区是C++内存模型的核心部分,通过预分配和长生命周期机制,支持全局和静态变量的高效存储。其工作原理确保了数据持久性和低运行时开销,但开发者需注意避免滥用(如过多全局变量可能导致内存浪费或初始化顺序问题)。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

I love LiLi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值