关于内存的一些知识

程序内存通常可以划分为以下几个区域:
  1. 栈区(Stack):由编译器自动分配和释放,主要存放函数的参数值、局部变量的值等。栈内存的特点是先入后出(FILO),即后声明的变量先释放,自动释放。
  2. 堆区(Heap):一般由程序员分配和释放,若程序员不释放,程序结束时可能由操作系统回收。堆内存的申请和释放是动态的,程序员可以灵活控制内存的大小和生命周期。
  3. 全局区(静态区)(Static Area):这个区域包含了全局变量和静态变量的存储。全局变量和静态变量在程序启动时被分配内存,在程序结束时由系统释放。这个区域可以进一步细分为已初始化的全局变量和静态变量存储区(通常称为BSS段之前的区域),以及未初始化的全局变量和静态变量存储区(BSS段)。
  4. 文字常量区:用于存储常量字符串等文字常量。
  5. 程序代码区:存放函数体的二进制代码。

各个内存区域位置以及其作用:
  1. 栈(Stack)

    **位置 :**通常位于内存的较低地址区域(但并非绝对),随着函数的调用和返回,栈顶指针会向上或向下移动。
    **用途:**用于存储局部变量、函数参数以及返回地址等。
    **特性:**后进先出(LIFO)的数据结构。

  2. 堆(Heap)

**位置:**通常位于栈的上方,但具体位置依赖于操作系统和程序的具体实现。
**用途:**用于动态分配内存,即程序在运行时根据需要申请和释放的内存区域。
**特性:**没有固定的大小,且由程序员(或程序库)显式管理内存的申请和释放。

  1. 数据段(Data Segment)

数据段通常被进一步细分为初始化数据段(Initialized Data Segment)和未初始化数据段(Uninitialized Data Segment,也称作BSS段)。
**初始化数据段:**存储程序中已初始化的全局变量和静态变量。
**未初始化数据段:**存储程序中未初始化的全局变量和静态变量。编译器在程序开始时自动将其初始化为0或null。

  1. 代码段(Code Segment 或 Text Segment)

**位置:**通常位于内存的高地址区域(但并非绝对),包含程序的机器码。
用途:存储程序的指令代码,即CPU执行的二进制指令。
**特性:**只读,程序执行时不能修改代码段的内容。

  1. 其他区域

**环境变量:**存储操作系统传递给程序的参数和环境设置。
**命令行参数:**传递给程序的参数通常存储在特定的内存区域中。
**动态链接库(DLLs)和共享库:**这些库文件在程序运行时被加载到内存中,通常位于代码段和数据段之外的特定区域。
虚拟内存示意图


全局变量和静态变量:
  1. 存储位置与生存周期

**全局变量:**全局变量通常存储在全局区(也称为静态区)。无论是已初始化的还是未初始化的全局变量,它们都被存储在相同或相邻的内存区域。这些变量的生存周期与程序的执行时间相同,即在程序启动时创建,在程序结束时销毁。
**静态变量:**静态变量同样存储在全局区,但与全局变量在存储位置上的主要区别在于其可见性和作用域。静态变量分为全局静态变量(常称为静态全局变量)和局部静态变量。全局静态变量在程序结束时释放,而局部静态变量的存储位置虽然在函数内部定义,但其存储方式与全局变量相同,也具有程序的整个执行周期。

  1. 作用域与可见性

**全局变量:**全局变量具有全局作用域,即在整个程序中都可以被访问。但需要注意的是,如果在一个源文件中定义了全局变量,在其他不包含该全局变量定义的源文件中需要使用extern关键字来声明这个全局变量,以便访问。
静态变量:
**全局静态变量:**其作用域被限制在定义它的文件内,即具有内部链接性。这意味着,尽管它在程序的全局区存储,但其他源文件无法直接访问它,除非通过某种形式的间接访问(如通过函数接口)。
**局部静态变量:**其作用域被限制在定义它的函数内,但它在函数调用结束后并不被销毁,而是保留其值直到程序结束。这意味着,在多次调用同一函数时,局部静态变量能够保持其上一次调用结束时的值。

  1. 初始化与赋值

**全局变量:**全局变量可以在定义时初始化,也可以不初始化。未初始化的全局变量会被系统自动初始化为0(对于数值型变量)或空字符(对于字符型变量)。
**静态变量:**无论是全局静态变量还是局部静态变量,都可以在定义时初始化。若未初始化,系统也会自动赋予它们初始值,规则与全局变量相同。此外,静态变量只被初始化一次,无论是在全局区还是在函数内部。

  1. 使用场景与影响

**全局变量:**全局变量因其全局作用域的特性,便于在不同函数或代码块之间共享数据。然而,这也带来了命名冲突、可变性风险和难以追踪等潜在问题。因此,在编程中应谨慎使用全局变量,并考虑使用其他机制(如局部变量、参数传递等)来传递和共享数据。
**静态变量:**静态变量(特别是局部静态变量)在需要跨函数调用保持状态或值时非常有用。它们提供了一种在不使用全局变量的情况下实现数据持久性的方法。然而,也需要注意静态变量的作用域和可见性限制,以避免不必要的复杂性。

/*
说人话:
全局变量和静态变量的最大区别就是作用域!!!
静态变量虽然生存周期是整个程序,但是其作用域还是在其被定义的函数中使用;
全局变量具有全局作用域,只需要在一个源文件中定义,就能作用域全部源文件,其他不包含的源文件可以使用extern关键子再次声明这个变量;
*/
<?php
   
   function add(){
      static $num;//生存周期是整个程序,作用域只有这个函数
      global $name;
      $name  = "yin";
      $num++;
      echo $num;
   }

   echo $name;//不输出name,因为还没定义
   add();//输出1
   echo $num . "<br>";//不输出num值,因为没有$num
   echo $name . "<br>";//在函数外也可以使用$name,因为$有全局作用域
   add();//输出2


?>

参考:C语言:内存分配—栈区、堆区、全局区、常量区和代码区_c 内存布局-CSDN博客
and
静态变量与全局变量_静态变量和全局变量的区别-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值