(不起眼但很致命)变量的生命周期以及static的相关用法

一、浅谈变量

变量分为全局变量和局部变量,如何简单地区别它们呢?很简单:全局变量是定义在大括号之外的,而局部变量是定义在大括号里面的。
举个简单的栗子:

int a = 0;
int main()
{
     
	int b = 0;
}

此时a是全局变量,而b是局部变量。

当全局变量与局部变量重名时,局部变量优先:

int a = 0;
int main()
{
     
	int a = 10;
	printf("%d", a);
}

输出结果为10;

二、变量的生命周期和static的相关用法

变量的创建到变量的销毁之间的时间段,叫做生命周期;

全局变量的生命周期是整个程序的生命周期(静态存储期);
局部变量的生命周期从进入作用域开始,出作用域结束(自动存储期);

让我们从一段代码入手,感受一下变量的销毁:

void fun()
{
     
	int a = 1;
	a++;
	printf("a=%d\n", a);
}
int main()
{
     
	int i = 0;
	while (i < 5)
	{
     
		fun();
		i++;
	}
	return 0;
}

不妨先看一看,品一品,思考一下结果是什么。
如果你认为是2,3,4,5,6的话,那么请仔细看下面的分析哦。
请跟着我的思路:主函数中i=0,此时进入while循环,然后又执行fun()函数,函数中定义了一个变量a,赋值为1,a++后变成2,所以第一个结果为2,然后回到主函数,i++变成2,再次进入循环,执行fun()函数,关键部分来了——上一次执行完fun()函数后,变量a就被自动销毁了,因为它走出了自己预定的作用域,也就是fun()函数的那对大括号{ },导致我们再次进入fun()函数时,a还是原先的那个1,然后剩下的就和第一次一样,导致每一次输出的a都是2;

怎样改进呢?这牵扯到static的一个用法。

static修饰局部变量的作用

想让上面的代码成功输出2,3,4,5,6?不妨在int a=1前加上一个static。

void fun()
{
     
	static int a = 1;//注意这里的变化!!!!
	a++;
	printf("a=%d\n", a);
}
int main()
{
     
	int i = 0;
	while (i < 5)
	{
     
		fun();
		i++;
	}
	return 0;
}

int a之前加上static之后,它的生命周期被延长,到整个程序结束的时候,a所在的这块内存才会被系统释放;那么这个时候,当我们第二次执行fun()函数时,a的值变成2,a++后变成3,然后输出……最终,我们得到的结果就是:a=2、a=3、a=4、a=5、a=6;

三、相关的雷区

观察一下代码:

int main()
{
     
    int count = 0;
    int i = 0;
    for (i = 1; i <= 2019; i++)
    {
     
        while (i)
        {
     
            if (i % 10 == 9)
            {
     
                count++;
                break;
            }
            i /= 10;
        }
    }
    printf("%d\n", count);
    return 0;
}

我们想要利用这段代码打印1到2019之间,包含9的数字(如19,29,2019…)的个数
当我们这行这段代码后我们发现,光标在闪烁但没有结果输出,很有可能这个时候,程序死循环了,所以我们来调试一下:
(不起眼但很致命)变量的生命周期以及static的相关用法_第1张图片
我们开始进入for循环,此时初始化后i=1,1≠0,进入while循环,1%10等于1而不是9,所以if循环进不去,计数器count也就无法增加。
(不起眼但很致命)变量的生命周期以及static的相关用法_第2张图片

然后执行i/=10(这里i/=10的作用就是遍历数字i的每一位)(不起眼但很致命)变量的生命周期以及static的相关用法_第3张图片
这时1/10得到0,所以i就等于0了,此时while的判断为0,第一次while循环结束,紧接着就该来到for循环的调整部分,也就是i++——
在这里插入图片描述
这里我们想的是,i=1不符合,那么第二次从i=2开始,但事实上,i的值刚刚经过除10之后,已经变为0,此时再i++,i还是变成1,然后判断i=1<=2019,进入for循环,然后又进入while循环……之后就这样无限循环下去了。
在这里插入图片描述
怎样避免这样的死循环发生呢?
于是我们想到,在创建一个变量 j来接收 i,然后让 j进入while循环,j的值被一次次修改,但此时i的值没有变,因而我们达到了遍历1到2019之间所有数字的目的。代码如下:

int main()
{
     
    int count = 0;
    int i = 0;
    for (i = 1; i <= 2019; i++)
    {
     
        int j = i;//这里引入新变量j接收每一次进来的i的值
        while (j)
        {
     
            if (j % 10 == 9)
            {
     
                count++;
                break;
            }
            j /= 10;
        }
    }
    printf("%d\n", count);
    return 0;
}

此时得到最终的结果,为544;

小结

以上的例子你是否都做对了呢?如果是,那么恭喜你,你对变量的生命周期还是很敏感的,如果不是,那么还需要在平时的学习中多多注意,多多练习,如果你写的代码最终结果不是所想的,说不定就是某个变量的生命周期没有弄清楚呢。

//创作不易,留个赞再走呗~

你可能感兴趣的:(编程语言,数据结构)