【从零开始的 C 语言笔记】第二十六篇-变数的生命周期(1)

上一篇我们介绍了副函式的概念,一般来说我们会把特别处理某些资料的部分,另外拉出一个副函式来处理,除了更好阅读之外,也会增加程序的可维护性,当某个功能出问题,只要专注处理负责该功能的函式就可以了。

虽然先前第六篇已经大概介绍过变数的用法跟概念了,不过今天我们来深入介绍变数的使用范围与生命周期吧!


变数的生命周期?

看到生命周期大家或许会有点困惑,变数就是变数还有生命吗?事实上变数会从被宣告的当下诞生,记忆体会分配一个位置给它,直到区块结束、程序结束後就不再有效,会不能存取也找不到它,我们称这个诞生到结束的过程为「变数的生命周期」。

一般介於「{ }」内的变数,变数存在的生命周期会仅限在内,超过「{ }」之外便会消亡,我们可以从以下程序码看见:

#include <stdio.h>

int main()
{
    int i = 10;

    printf("%d\n",i);
    for(int i=0; i<5; i++){
        printf("%d\n",i);
    }
    printf("%d\n",i);

    return 0;
}

https://ithelp.ithome.com.tw/upload/images/20211122/20142565hjPFRkCpVU.png

第一次宣告的变数是在main function的整数i(为10),而第一次列印的结果也是10。

但第二次宣告的变数在for回圈中,且为递增的变数i,并随着for回圈列印了0到4,而不是for回圈外的10。

但当for回圈结束後,列印出的变数则是第一次宣告的10。
https://ithelp.ithome.com.tw/upload/images/20211122/20142565DrPm1xjsMB.png


区域变数、全域变数?

先前我们有提到如果变数被宣告在「{ }」的区域内,那在超过「{ }」的范围後就会消亡,所以我们不可能在变数宣告的区域范围外使用它,而我们称这种变数为「区域变数」;那如果我们要宣告一个全程序区域都可以使用的变数,也就是「全域变数」时要怎麽做呢?

  1. 区域变数

(1) 以函式为范围
但凡离开宣告变数的「{ }」范围外,变数便不可再使用,且主函式宣告的变数,在副函式是不可以使用的,因副函式已经出了主函式范围之外。

#include <stdio.h>

void test();

int main()
{
    int x = 10;

    printf("%d\n",x);
    test();
    printf("%d\n",x);

    return 0;
}

void test(){
    int x = 5;
    printf("%d\n",x);
}

https://ithelp.ithome.com.tw/upload/images/20211122/20142565tXF89AI5Qx.png

如同列印结果,主函式宣告的变数出了主函式范围,在副函式是不可使用变数的,但在副函式宣告同名变数并不冲突,只是副函式宣告的变数,也只能在副函式中使用。
https://ithelp.ithome.com.tw/upload/images/20211122/20142565gCdFiWhB2D.png
https://ithelp.ithome.com.tw/upload/images/20211122/20142565GCpXSdbCmZ.png
(2) 以小区块为范围
前面有提到若离开宣告变数的「{ }」范围外,变数便不可再使用,但若在范围之内的小区块(如for、while、if等等区块)又宣告同名变数,则在小区块内变数将以小区块变数覆盖,但一出小区块范围也不可使用。

#include <stdio.h>

int main()
{
    int i = 10;

    printf("%d\n",i);
    for(int i = 1; i<=5; i++){
        printf("%d\n",i);
    }
    printf("%d\n",i);

    return 0;
}

https://ithelp.ithome.com.tw/upload/images/20211122/20142565ZMLjKuJt8F.png
如同列印结果,在for回圈区块内又宣告同名变数,在其区块范围内会暂时覆盖,直到离开该区块则区块变数便不可使用。
https://ithelp.ithome.com.tw/upload/images/20211122/20142565yCuNHIIzCV.png
https://ithelp.ithome.com.tw/upload/images/20211122/20142565J21AymszOy.png
2. 全域变数
如果要宣告一个全程序都可以使用的「全域变数」,我们将宣告在主函式外,通常为主函式部分之前。

#include <stdio.h>

int x = 15;
int main()
{
    printf("%d\n", x);
    test();
    printf("%d\n", x);

    return 0;
}

void test(){
    printf("%d\n", x);
}

https://ithelp.ithome.com.tw/upload/images/20211122/20142565gLnUuH7kgd.png
可以从结果看到若宣告为全域变数,且未被区域的同名变数覆盖的话,程序的全区域都可以使用这个变数。
https://ithelp.ithome.com.tw/upload/images/20211122/20142565ICHx5Z7vZa.png


小结

  1. 变数是有使用的范围的,且出了范围就会自动消亡,而变数诞生至消亡则为变数的生命周期。

  2. 非全程序可使用之变数为区域变数,反之则是全域变数。

  3. 主函式宣告之变数,出了主函式便不可使用(如到了副函式时);副函式宣告之变数,出了副函式便不可使用(如回到主函式或任何不在副函式范围的地方);被小区块(for、while、if等区块)宣告之变数,出了小区块後便不可使用。

  4. 变数是可以被不同范围的同名区域变数覆盖的。


看到这里就大概学习完什麽是变数的生命周期,还有区域变数、全域变数的不同了,弄清楚变数的存在、使用范围是很重要的事情,希望大家看完可以比较好理解!

下一篇我们来继续介绍变数的生命周期,如果出了范围就会消失,那有没有可以被保存、一直存在的变数呢?


<<:  从CISSP答题培养有依据的猜测与决策能力 (Educated Guess and Informed Decision)

>>:  为了转生而点技能-javascript,day4(初探型别

均线 - 支撑与压力

在技术面上,我们常听到支撑跟压力,今晚来说明一下,支撑型态与压力型态 以光宝科2301来说 上升趋势...

Youtube Analytics API 教学 - 打破地理位置的界线 'country' 维度

「鲑鱼均,因为一场鲑鱼之乱被主管称为鲑鱼世代,广义来说以年龄和脸蛋分类的话这应该算是一种 KNN 的...

[Day 26] 趋势化资料实作(一)

MA线 收盘 > MA,看多 收盘 < MA,看空 data_df.loc[:, &qu...

从零开始学习3D游戏开发:程序基础 Part.3 回圈

这是 Roblox 从零开始系列,入门章节的第六个单元,在这个单元你将学到 Lua 程序语言中非常重...

聊聊structure concurrency 结构化并发

前面我们谈了,coroutine的coroutineScope、继承、异常处理和取消,也在文中提到了...