查看: 136|回复: 1

C++ static

[复制链接]

3

主题

9

帖子

18

积分

新手上路

Rank: 1

积分
18
发表于 2022-11-15 12:58:35 | 显示全部楼层 |阅读模式
内存的五大区

按照地址从高到低排列: 栈区 -> 堆区 -> 全局静态区 -> 常量区 -> 代码区
栈区

  • 函数内部定义的局部变量和数组,都存放在栈区。
  • 栈区的内存空间由系统管理。(函数调用时开辟空间,函数调用结束时回收空间)
  • 栈是从高地址向低地址扩展,是一块连续的内存区域,遵循 FILO 先进后出原则,效率高。
  • 栈区一般在运行时进行分配
堆区

  • 空间最大,由程序员手动管理。(ARC 自动管理)
  • 堆是从低地址向高地址扩展。
  • malloc、calloc、realloc 相关函数管理。
  • 堆区开辟空间,可以是不连续的内存区域,以链表结构存在(增删快,查找慢)。返回首地址存放在栈区。
  • free 回收。释放对象在堆区的内存,并将栈中的地址指针置空。
全局静态区

  • 存放全局变量和静态变量(局部静态变量、全局静态变量、类静态成员)
  • 空间由系统管理。(程序启动时,开辟空间;程序结束时,回收空间;程序执行期间一直存在)
  • static 修饰的变量仅初始化一次,生命周期为整个程序运行期
全局静态存储区又分为 DATA 段和 BSS 段。DATA 段(全局初始化区)存放初始化的全局变量和静态变量;BSS 段(全局未初始化区)存放未初始化的全局变量和静态变量。
常量区

  • 存放常量(整型、字符型,浮点,字符串等),整个程序运行期不能被改变。
  • 空间由系统管理,生命周期为整个程序运行期。
代码区
存放程序执行的 CPU 指令。(编译期将代码转换为 CPU 指令)
static 使用场景


  • 函数内部定义的变量在函数结束时会释放掉,如果想将函数中此变量的值保存至下一次调用时。
  • 需要一个数据对象为整个类而非某个对象服务,同时又力求不破坏类的封装性,即要求此成员隐藏在类的内部,对外不可见时,可将其定义为静态数据。
static 全局变量

static 修饰全的局变量只能在本文件中访问,不能在其它文件中访问,即便是 extern 外部声明也不可以。static 修饰的函数只能在本文件中调用,不能被其他文件调用。全局变量默认是有外部链接性的,作用域是整个工程,在一个文件内定义的全局变量,在另一个文件中,通过 extern 全局变量名的声明,就可以使用该全局变量。
未经初始化的 static 全局变量会被程序自动初始化为 0 (在函数体内声明的自动变量的值是随机的,除非它被显式初始化,而在函数体外被声明的自动变量也会被初始化为 0)。
static 局部变量

static 局部变量不会在函数内分配空间。在程序执行到该变量的声明处时被首次初始化,即以后的函数调用不再进行初始化,而且它始终驻留在全局数据区,直到程序运行结束以后才释放,但其作用域为局部作用域。如果没有显式初始化,会被程序自动初始化为 0。
static 类成员

类中的 static 成员变量不会在类内分配空间。故不能在类的声明中定义。它也不能在头文件中类声明的外部定义,因为那会造成在多个使用该类的源文件中,对其重复定义。一般是在应用程序的 main() 函数前的全局数据声明和定义处定义。且必须先初始化再使用
static 修饰的类成员是属于整个类的而不是某个实例化对象的,可以通过 类名::静态成员名 直接引用,而不需要实例化出一个类来。他是类实例之间共享的。而不能通过类名来直接调用类的非静态成员函数。
因为 static 成员函数属于整个类,在类实例化对象之前就已经分配空间了,而类的非静态成员必须在类实例化对象后才有内存空间,所以 static 成员函数中不能使用类的非静态成员,只能使用类的 static 成员。而类的非静态成员函数可以使用类的 static 成员。
非静态成员函数有 this 指针,而静态成员函数没有 this 指针。
回复

使用道具 举报

4

主题

11

帖子

23

积分

新手上路

Rank: 1

积分
23
发表于 2025-3-13 16:50:01 | 显示全部楼层
占位编辑
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表