C 生命周期和作用域

生命周期和作用域

  • 变量分类

    • 局部变量 (声明在某个函数里)和 全局变量(声明在所有函数外面)
    • 静态变量 和 非静态变量
  • 变量的使用范围

    • 作用域:可以使用这个变量的所有语句的总和
    • 生命周期:某个变量能够使用的时间范围
  • 非静态局部变量

    • 作用域是包含函数里面的所有语句
    • 生命周期是函数某一次执行的时间
    • 类似于别墅里的家具(整个程序一个大型住宅区,里面若干个文件比作若干个小区,函数相当于某小区的一栋别墅),别的别墅里的人无法使用这个家具,而且只有这个别墅构建好了,那个家具才存在。别墅拆了,家具也没了。
  • 静态局部变量

    • 作用域包含函数里的所有语句
    • 生命周期是整个程序的执行时间(函数执行前与结束后都可以使用)
    • 类似于别墅下面的土地,只有这家别墅可以使用,但这些土地是一直存在的一直可以使用的,并不是有了别墅以后才有的,别墅拆了以后土地依然存在,依然可以使用。
  • 非静态全局变量

    • 作用域包含程序里的所有语句
    • 生命周期是整个程序的执行时间
    • 类似于小区外面的道路,道路是公共的,所有人都可以使用它。另外这些道路在没有这些小区的时候也是存在的,小区拆除了,道路依然存在,依然可以使用。
  • 静态全局变量

    • 作用域包含文件里的所有语句
    • 生命周期是整个程序的执行时间
    • 类似于小区里的路,小区之间是相互封闭的,别的小区不能使用这个小区的路,另外小区道路的存在也不受别墅的影响。
  • 注意事项

    • 全局变量和静态变量的初始化只在程序开始的时候执行一次(不管它们被写在什么地方)
    • 全局变量和静态变量都会被自动初始化为0(如果没有明确初始化)
    • 非静态局部变量如果没有初始化,那么它的内容是随机的
  • 生命周期的意义在计算斐波那契数列效率上的体现

//用递归的思想来处理斐波那契数列
#include <stdio.h>
int fei(int sn) {
    if (sn <= 1 ){
        return 1; //分支处理递归函数不可处理的分解后的问题
    }
//分解问题:要想算编号为 sn 的数字,需要算出编号为 sn-1 和 sn-2 的数字,然后相加
    return fei(sn -2) + fei(sn -1); //假设递归函数已经写好,分别用参数sn-2 和 sn-1去调用fei
}

int main() {
    int sn = 0;
    printf("请输入编号: ");
    scanf("%d", &sn);
    printf("结果是%d\n", fei(sn));
    return 0;
}

为了计算编号为40的数字需要把编号为38的数字计算两次,把编号为36的数字计算了3次,把编号为10的数字可能计算了上千遍。
在这里插入图片描述
下面来提高这个程序的运行速度,用一个数组来保存已经算过的数字,保证每个编号对应的数字只被算了一次

#include <stdio.h>
int fei(int sn) {
    int arr[50] = {0};
    if (sn <= 1 ){
        return 1; 
    }
    //先检查数组里有没有放那个编号对应的数字,这个分支去处理数组里还没有放好数字的情况
    if (!arr[sn - 2]) {
        arr[sn - 2] = fei(sn-2);
    }
    if (!arr[sn - 1]) {
        arr[sn - 1] = fei(sn-1);
    }
    return arr[sn -2] + arr[sn -1]; 
}

int main() {
    int sn = 0;
    printf("请输入编号: ");
    scanf("%d", &sn);
    printf("结果是%d\n", fei(sn));
    return 0;
}

然后发现时间更长了,因为 arr[50]是一个非静态局部变量,程序在运行时,内存里会有很多个数组一起存在,每个fei函数只能使用它自己的数组,因此这个fei函数是永远也不可能从这个数组得到别的fei函数以前计算好的数字。最后结果是不但以前做的事情一件都没有少做,还花费了些时间为这些数组准备存储区。

方法一: static int arr[50]; //数组不需要初始化,静态变量都会被自动初始化为0,静态局部变量的生命周期就是整个程序的执行时间,这就意味着所有的fei函数用的都是同一个数组。

方法二: int arr[50]; //做全局变量,生命周期也是整个程序的执行时间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值