【C语言冷知识】03_作用域和生命周期,变量的自我修养

文章目录

  • 01 - 变量的作用域和生命周期
  • 02 - 变量的作用域
  • 03 - 变量的生命周期
  • 04 - 回答问题


01 - 变量的作用域和生命周期

  上一文我们从上帝的视角去看变量,看透了变量的本质,是一段有定义、有意义和可变的内存,这仅仅是她的语法和语义,落实到编程中,她是程序员进行创建和调用的,既然能在代码这个大千世界里面担任重要的角色,那么她就一定有属于自己的魅力之处,作用域和生命周期便是她的自我修养。变量的自我修养非常重要,她关乎到代码的设计,老规矩,我们先抛出几个问题:
  1、超过了作用域,生命周期的作用是什么?
  2、程序能知道变量的生命周期结束了吗?
  3、生命周期是动态的还是静态的?
  要搞清这些问题,必须先知道作用域和生命周期的本质是什么,知道本质方可解题。
【C语言冷知识】03_作用域和生命周期,变量的自我修养_第1张图片

02 - 变量的作用域

  作用域:能够通过变量名去访问这个变量的区域
  注意作用域强调的一定是通过变量名进行访问,通过指向变量的指针不算,干涩难懂?举个例子:

int* IncAndGetVar(void)
{
    static int Num = 0;
    Num++;
    
    return &Num;
}

void Func(void)
{
    int* pVar = IncAndGetVar();
    *pVar += 2;
}

  以上代码中,变量Num的作用域仅仅是IncAndGetVar函数内部,在Func()函数中没有Num的作用域。因为Num是IncAndGetVar()函数的静态局部变量,Num这个变量名只在函数内可见,因此Num的作用域只在IncAndGetVar()函数内,即使Func()函数得到了Num的地址并且改变了Num的值,但是并非使用变量本身的名字进行操作,所以超出了IncAndGetVar(),就超出了变量Num的作用域。这里可以得出一个结论:超出了作用域,也能访问到变量(通过地址),前提是生命周期依然存在。

【C语言冷知识】03_作用域和生命周期,变量的自我修养_第2张图片

  知道本质后,关于什么全局静态、局部静态、全局自动变量等等的作用域还需要去背吗?不需要了,可以看名字就推导出作用域:
  全局自动变量:只要声明了该变量(extern xxx)和定义它的本文件且不存在同名的局部变量区域内,都是它的作用域,可以理解为工程内所有区域,如果全局和局部同名时,操作局部会屏蔽全局
  全局静态变量:只在定义它的文件且不存在同名的局部变量区域内,因为静态原因,其变量名其它文件不可见,同时如果全局和局部同名时,操作局部会屏蔽全局
……

03 - 变量的生命周期

  生存期:能够访问这个变量的时间段
  注意生命周期强调的是能够访问,访问有2种,1是变量名,2是指针,只要其中一种能够访问并且有效,那么生命周期就存在,于是判断变量的生命周期是否存在,就取决于它是否在内存有效,还是上面的例子:

int* IncAndGetVar(void)
{
    static int Num = 0;
    Num++;
    
    return &Num;
}

void Func(void)
{
    int* pVar = IncAndGetVar();
    *pVar += 2;
}

  变量Num的生命周期是整个程序运行阶段都存在的,因为它是局部静态变量,只要程序在运行,它就存在于内存当中,在内存有效,就有办法去访问它。
  变量pVar的生命周期是Func()函数的内部,因为它是局部自动变量,函数Fcun调用结束后,pVar的空间将被编译器释放,一旦释放,此变量在内存就没有一席之地了,也就是无效,变量在内存中无效后,生命周期就随之结束。

  随后会有一个疑问,如果Num是局部自动变量呢?也就是下面:

int* IncAndGetVar(void)
{
    int Num = 0;
    Num++;
    
    return &Num;
}

void Func(void)
{
    int* pVar = IncAndGetVar();
    *pVar += 2;
}

  这样子学过C指针的估计都知道,这样程序一旦运行就可能会崩溃,因为局部自动变量在函数调用结束后,它的生命周期就结束了,本来它所占用的位置会被其他人占用,也就是它在内存已经无效,不能再去访问它。

04 - 回答问题

  1、超过了作用域,生命周期的作用是什么?
  超过了作用域,如果生命周期依然存在的话,生命周期的作用是让变量始终在内存有效,等着被访问,不能消失,就像站着茅坑不拉屎一样。

  2、程序能知道变量的生命周期结束了吗?
  不能知道,因为无法知道内存是否有效。

  3、生命周期是动态的还是静态的?
  是动态的,函数被调用的时候,局部变量生命周期存在,函数结束的时候,局部变量生命周期消失。

你可能感兴趣的:(C语言冷知识,C语言)