96SEO 2026-02-23 15:11 1
如果您只是想回顾或了解一下static和全局变量的异同点那么下面的总结将满足您的需求。

如果您是一位初学者或对二者的使用模棱两可建议您读完该篇文章相信这一篇将解答完您对于static关键字以及全局变量的所有疑惑。
全局变量全局变量在整个程序中都是可见的可以在任何函数中访问。
静态变量静态变量的作用域仅限于声明它的函数或文件。
如果在函数内部声明静态变量那么该静态变量只在该函数内部可见如果在文件内部声明静态变量那么该静态变量只在该文件内部可见。
全局变量如果没有初始化编译器会自动初始化为0。
静态变量如果没有初始化编译器也会自动初始化为0。
类内成员变量需要类内声明类外定义定义时可以使用默认初始化
全局变量全局变量在所有函数外部声明。
静态变量在变量类型前加上关键字static来声明静态变量可在任意位置。
全局变量当需要在多个函数或文件中共享数据时可以使用全局变量。
静态变量当需要保持变量的值在函数调用之间不变时可以使用静态变量。
总的来说全局变量和静态变量都有全局的生存期但是静态变量的作用域可以是局部的因此静态变量相对于全局变量来说可以更好地保护数据减少了数据被误操作的风险。
生命周期变量从定义到销毁的时间范围。
堆内存和栈内存章节介绍了一下程序的内存管理有一部分是Global
Segment全局段负责存储静态变量和全局变量存储在全局段的变量生命周期等于整个程序的运行时间。
变量的可见代码区域块作用域、函数作用域、类作用域和全局作用域。
不管是在全局还是局部声明的static变量都存放在程序的全局段但是它的作用域却不等同于生命周期它的作用域决定于它所被定义的位置。
从上述两点可以发现静态变量和全局变量具有相同的全生命周期存储在内存的静态存储区但是二者的作用域却不尽相同。
初始化时机全局变量、文件域中的静态变量、类中的成员静态变量在main函数执行前初始化饿汉式局部变量中的静态变量在第一次调用时初始化懒汉式。
在类中声明的静态成员变量还必须要在类外定义下才可以使用否则会编译报错。
静态成员变量不属于任何一个对象对象的数据中不应该包含静态成员的数据。
所以在定义类的时候不会给静态变量分配内存只是声明因此就要在其他地方分配即定义。
声明向编译器声明或介绍了变量的名称类型或者函数及其参数类型等信息。
声明并不分配存储空间。
你可以多次声明同一个变量。
定义它除了向编译器声明或介绍了变量的名称类型等信息外还分配了存储空间。
换句话说定义是声明的扩展。
你只能一次定义一个变量。
也可以顺便初始化。
程序中变量有且只有一个定义更能说明为什么要在类外再定义下类的静态成员变量了。
在C中如果你试图多次定义同一个变量编译器会报错。
但是你可以多次声明同一个变量只要它在某个地方被定义过一次。
所以所有的定义包括变量和函数都是声明但并非所有的声明都是定义。
全局变量是在所有函数外部定义的变量其作用域是从定义点开始到文件结尾。
全局变量可以被任何函数访问和修改即全局变量的生命周期是整个程序的执行期间。
声明全局变量全局变量在所有函数之外定义通常是在程序的开头。
例如int
使用全局变量在任何函数中直接使用变量名即可访问全局变量。
例如x
如果全局变量和局部变量同名那么在局部作用域中局部变量会覆盖全局变量。
如果想在局部作用域内访问全局变量需要使用::全局作用域解析运算符。
例如::x
在一个文件中定义的全局变量如果想在另一个文件中使用需要在另一个文件中用关键字
其他文件不能再定义一个与其相同名字的变量了否则编译器会认为它们是同一个变量。
尽量避免使用全局变量因为全局变量会破坏数据的局部性使得程序的理解和调试变得困难同时也增加了数据的不安全性。
假设我们有两个文件一个是main.cpp一个是other.cpp。
在main.cpp文件中我们定义了一个全局变量并在main函数中使用该全局变量。
}在other.cpp文件中我们想要使用main.cpp中定义的全局变量x因此其他文件中需要用extern关键字声明该全局变量。
}如果我们有一个局部变量和全局变量同名那么在这个局部作用域中局部变量会覆盖全局变量。
接下来是static关键字笔者按照面向过程不引入类的概念和面向对象类内的static两个角度展开static关键字的使用。
在全局变量前加上关键字static该变量就被定义成为一个静态全局变量(相当于限制作用域的全局变量作用域仅为当前文件内)。
Segment中分配内存默认初始化未经初始化的静态全局变量会被程序自动初始化为0自动变量的自动初始化值是随机的作用域有限
静态全局变量在声明它的整个文件都是可见的而在文件之外是不可见的静态变量都在全局数据区分配内存包括后面将要提到的静态局部变量。
对于一个完整的程序在内存中的分布情况如下【代码区】【全局数据区】【堆区】【栈区】一般程序的由new产生的动态数据存放在堆区函数内部的自动变量存放在栈区静态数据即使是函数内部的静态局部变量存放在全局数据区。
自动变量一般会随着函数的退出而释放空间而全局数据区的数据并不会因为函数的退出而释放空间。
定义全局变量就可以实现变量在文件中的共享但定义静态全局变量还有以下好处
静态全局变量不能被其它文件所用其它文件中可以定义相同名字的变量不会发生冲突
这就是因为静态全局变量不能被其它文件所用即使在其它文件中使用extern
因此在一个文件中静态全局变量和全局变量功能相同而在两个文件中要使用同一个变量则只能使用全局变量而不能使用静态全局变量。
在局部变量前加上关键字static该变量就被定义成为一个静态局部变量(作用域更狭窄的全局变量全生命周期局部变量的作用域)。
}在函数fn_local()定义了一个变量每当程序运行到该语句时都会给该局部变量分配栈内存。
但随着程序退出函数体系统就会收回栈内存局部变量也相应失效。
但有时候我们需要在两次调用之间对变量的值进行保存。
通常的想法是定义一个全局变量来实现。
但这样一来**变量已经不再属于函数本身了不再仅受函数的控制**这给程序的维护带来不便。
静态局部变量正好可以解决这个问题。
静态局部变量保存在全局数据区而不是保存在栈中每次的值保持到下一次调用直到下次赋新值。
静态局部变量在全局数据区分配内存静态局部变量在程序执行到该对象的声明处时被首次初始化即以后的函数调用不再进行初始化静态局部变量一般在声明处初始化如果没有显式初始化会被程序自动初始化为0静态局部变量始终驻留在全局数据区直到程序运行结束。
但其作用域为局部作用域当定义它的函数或语句块结束时其作用域随之结束
在函数的返回类型前加上static关键字,函数即被定义为静态函数。
静态函数与普通函数不同它只能在声明它的文件当中可见不能被其它文件使用。
静态函数不能被其它文件所用其它文件中可以定义相同名字的函数不会发生冲突
在类内成员变量的声明前加上关键字static该数据成员就是类内的静态数据成员。
6);N.GetSum();M.GetSum();return
静态成员变量是该类的所有对象所共有的。
对于普通成员变量每个类对象都有自己的一份拷贝。
而静态成员变量一共就一份无论这个类的对象被定义了多少个静态成员变量只分配一次内存由该类的所有对象共享访问。
所以静态数据成员的值对每个对象都是一样的它的值可以更新因为静态数据成员在全局数据区分配内存由本类的所有对象共享所以它不属于特定的类对象不占用对象的内存而是在所有对象之外开辟内存在没有产生类对象时其作用域就可见类作用域。
因此在没有类的实例存在时静态成员变量就已经存在我们就可以操作它静态成员变量存储在全局数据区。
static
成员变量的内存空间既不是在声明类时分配也不是在创建对象时分配而是在定义初始化时分配。
静态成员变量必须初始化而且只能在类体外进行。
否则编译能通过链接不能通过。
在示例中语句int
Myclass::Sum0;是定义并初始化静态成员变量。
初始化时可以赋初值也可以不赋值。
如果不赋值那么会被默认初始化一般是
Myclass::Sum;)。
静态数据区的变量都有默认的初始值而动态数据区堆区、栈区的变量默认是垃圾值。
static
变量一样编译时在静态数据区分配内存到程序结束时才释放。
这就意味着static
成员变量不随对象的创建而分配内存也不随对象的销毁而释放内存。
而普通成员变量在对象创建时分配内存在对象销毁时释放内存。
静态数据成员初始化与一般数据成员初始化不同。
初始化时可以不加
成员变量都可以用这种方式初始化。
静态数据成员初始化的格式为数据类型类名::静态数据成员名值类的静态成员变量访问形式1
(类已经被实例化)类对象名.静态数据成员名类的静态成员变量访问形式2类类型名::静态数据成员名也即静态成员不需要通过对象就能访问。
静态数据成员和普通数据成员一样遵从public,protected,private访问规则如果静态数据成员的访问权限允许的话即public的成员可在程序中按上述格式来引用静态数据成员
设置静态成员变量和函数这种机制的目的是将某些和类紧密相关的全局变量和函数写到类里面看上去像一个整体易于理解和维护。
如果
想在同类的多个对象之间实现数据共享又不要用全局变量那么就可以使用静态成员变量。
也即静态数据成员主要用在各个对象都有相同的某项属性的时候。
比如对于一个存款类每个实例的利息都是相同的。
所以应该把利息设为存款类的静态数据成员。
这有两个好处
不管定义多少个存款类对象利息数据成员都共享分配在全局数据区的内存节省存储空间。
一旦利息需要改变时只要改变一次则所有存款类对象的利息全改变过来了。
静态成员变量没有进入程序的全局命名空间因此不存在与程序中其它全局命名冲突的可能不会污染命名空间。
可以实现信息隐藏。
静态成员变量可以是private成员而全局变量不能。
静态成员函数为类服务而不是为某一个类的具体对象服务。
静态成员函数与静态成员变量一样都是类的内部实现属于类定义的一部分。
普通成员函数必须具体作用于某个对象而静态成员函数并不具体作用于某个对象。
this指针(可以参见文章C中的this指针和Python中的Self)this指针指向类的对象本身指向实例化后的对象的地址因为普通成员函数总是具体地属于类的某个具体对象的。
当函数被调用时系统会把当前对象的起始地址赋给
指针。
通常情况下this是缺省的。
如函数fn()实际上是this-fn()。
与普通函数相比静态成员函数属于类本身而不作用于对象因此它不具有this指针。
正因为它没有指向某一个对象所以它无法访问属于类对象的非静态成员变量和非静态成员函数它只能调用其余的静态成员函数和静态成员变量。
从另一个角度来看由于静态成员函数和静态成员变量在类实例化之前就已经存在可以访问而此时非静态成员还是不存在的因此静态成员不能访问非静态成员。
Student::getAverage()endl;return
出现在类外的函数定义时不能指定关键字static静态成员之间可以相互访问即静态成员函数仅可以访问静态成员变量、静态成员函数、静态变量静态成员函数不能访问非静态成员函数和非静态成员变量非静态成员函数可以任意地访问静态成员函数和静态数据成员由于没有this指针的额外开销静态成员函数与类的全局函数相比速度上会稍快调用静态成员函数两种方式
通过成员访问操作符(.)和(-)也即通过类对象或指向类对象的指针调用静态成员函数。
直接通过类来调用静态成员函数。
类名::静态成员函数名参数表。
也即静态成员不需要通过对象就能访问。
https://zhuanlan.zhihu.com/p/37439983
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback