C语言中变量的存储类别——auto和static

我决定不再说些暖场的废话了,很尴尬。。

c语言中的存储类别可分为auto、static、register和extern,后两者不常用,研究下前两个。

auto即自动,用此关键字修饰变量为自动的,亦即当执行到定义该变量的代码时会产生一个新的变量,我们做个小实验:

#include 
#include 
#include 
void test() 
{
	auto int a = 0;
	a = a++;
	printf("a=%d\n", a);
	printf("&a=%x\n", &a);
}
int main()
{
	printf("First:\n");
	test();
	printf("Second:\n");
	test();
	system("pause");
    return 0;
}

之前程序运行结束就闪退了,于是加入了system("pause"),看下结果:

C语言中变量的存储类别——auto和static_第1张图片

       可以看到调用两次test()函数得到的a值均为1,表明第二次的调用不会“记忆”第一次的值,这也是普通局部变量的特性,但问题在于,两次调用函数产生的新变量地址是一样的,从之前的认知来看,第一次调用结束后定义的a变量也就随之释放了,那这里的“释放”指的是什么呢,难道只是“值”的释放而没有释放所占据的内存单元,为了排除巧合,我们再调用一次test()函数,结果为:

C语言中变量的存储类别——auto和static_第2张图片

       可以看出虽然每次运行程序操作系统给分配的内存是不同的,但三次调用test()函数产生的新变量a都是占据一样的内存单元,我们继续加码,在每次调用之间加上延迟函数,设置一分半钟的空闲时间,排除由于调用间隔时间太短致使系统分配同一内存(即刚释放完内存又分配到该内存单元)的情况,延迟函数为:

Sleep(90000);

看下结果:

C语言中变量的存储类别——auto和static_第3张图片

      依旧如此,继续加码,我们在每次调用中间再定义新的变量,按照常规思维,当释放掉A内存单元后随之定义变量应该会占据A或者A之后的单元,先看下部分代码:

printf("First:\n");
test();
Sleep(90000);
int b = 10;
printf("&b=%x\n", &b);
Sleep(90000);
printf("Second:\n");
test();
Sleep(90000);
int c = 100;
printf("&c=%x\n", &c);
printf("Third:\n");
test();

我们在三次调用中插空定义了变量b和c,先看结果:

C语言中变量的存储类别——auto和static_第4张图片

       神奇,b和c的存在完全没有影响到三次调用test()函数生成的a,当然这里的内存分配还涉及到一个分配顺序的问题,记得之前的博客中提到过,即先声明的变量后分配地址,貌似是这么个意思。

       到这里是不是就可以理解成,普通的局部变量(auto变量)调用结束便释放给内存的值,但保留该地址,这就有点意思了,或许是我知识面太窄了,如果这是一个基本常识的话还望大家告知一二,不胜感激~~对了,在定义局部变量时auto是默认的存储类别,所以可以省略掉。

        static声明的变量为静态变量,我们这里只考虑局部静态变量,这样方便和上边的auto变量进行对比,将代码中的auto改为static,其他的都不变,看下结果:

C语言中变量的存储类别——auto和static_第5张图片

       每次调用得到的a地址依旧不变,但数值依次加1,说明第一次定义的静态变量a没有因为调用程序结束而释放掉值,并且第二三次的调用“记忆”了该值,也可以说该变量进行了一次初始化,之后再调用时则保持上一次执行后的值。

       大体就是这些东西,很小的一个知识点,但之前对此一直存在着误解,希望以后多多研究一下内存吧,这一块很有意思~

最后想起一个小的点 , 关于auto和static声明的变量默认初始值问题 , 将test()函数改为:

auto int a;
static int b;
printf("a=%d\n", a);
printf("b=%d\n", b);
printf("&a=%x\n", &a);
printf("&b=%x\n", &b);

并在主函数中去掉定义的b和c以及延迟函数 , 看下结果:

C语言中变量的存储类别——auto和static_第6张图片

       不难发现static类型的整型变量默认为0 , 而auto类型的变量初始值存在随机性 , 说不定出现什么值 , 因此在声明普通局部变量时最好进行初始化 ;  还有就是我们之前一直在提局部变量 , 对于全局变量来说 , 定义整型变量默认值为0 , 此时肯定是不能用auto修饰的 , 否则编译器会报错 , 因此可以理解成auto只能修饰局部变量 , 该变量存在于栈中 , 因此可以动态分配 ; 而全局变量则存在于静态存储区~

如果文章对您有一点点帮助,还请打赏一二,您的鼓励是我前进的不竭动力

C语言中变量的存储类别——auto和static_第7张图片

你可能感兴趣的:(C语言的小屋,auto,static,存储类别)