失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > C语言——变量篇(一)变量关键字static auto extern register

C语言——变量篇(一)变量关键字static auto extern register

时间:2020-02-09 11:47:35

相关推荐

C语言——变量篇(一)变量关键字static auto extern register

前言:笔者最近在看C语言时候遇到了一堆关键字,auto,static,extern,register等等。看上去头皮发麻,在这里整理一下,便于自己理解。

全局变量和局部变量

关于全局变量和局部变量,笔者看过网上和书上各种解释,也是一头雾水,不能完全理解。在本篇中,笔者给出自己理解的全局变量和局部变量的定义如下:

全局变量:定义在模块外的变量。(这里的模块指被一对{}包围的内容)局部变量:定义在模块内的变量。

变量的作用域和生存期

对于一个变量,从时空角度上来说,它有两个重要的属性:作用域和生成期。

作用域:在这个范围内,变量可以被读写;在这个范围之外,变量不能被访问。生存期:在这个周期内,变量能够存在于它被分配的存储区内;超过这个周期,变量被销毁,即它原来所占用的存储期可能另作他用。

变量和存储类型关键字

对于全局变量和局部变量,变量的作用域和生存期,笔者以前总是笼统的以为,全局变量的生存期就是整个程序运行期间,局部变量的生存期是模块程序运行期间。但其实不能以偏概全,要结合存储类型关键字一起来看。

=================================================

1 存储关键字:static1.1 生存期: 我们都知道,程序的存储区可以分为代码区和数据区,而数据区又可以分为静态存储区和动态存储区。使用static关键字修饰的变量存储在静态存储区。编译器会给未初始化的静态变量初始化为0,并且它存在于整个程序运行期间。1.2 作用域: 如果是在模块外使用static,则该变量的作用域是该文件;如果是在模块内使用static,则该变量的作用域是该函数

=================================================

2 存储类型关键字:auto

2.1 生存期:auto关键字用于声明变量存储在动态存储区,在函数调用时生成,在函数退出时销毁。

2.2 作用域:auto用于模块内的局部变量的存储类型声明,只作用于该函数,可缺省。当缺省时,编译器将模块内的局部变量默认为auto类型。auto类型的变量在声明后,如果用户未对其进行初始化赋值,那么编译器也不会对其初始化赋值,这是和static区分开来的一个重要标志。

2.3 为什么static类型会被初始化为0,而auto类型则不会?

我们知道内存数据掉电易失,而刚刚给内存上电时,它的状态不稳定,每个内存单元中很可能受到干扰产生一些随机数。因此,通常我们会在上电时,给内存单元进行0赋值操作,即清零操作

static类型变量被分配在全局数据区,所以在它被分配到的是一块值已经被赋为0的空间。 而auto类型的数据属于模块内部,在调用函数,把函数模块压入调用堆栈的时候,该变量才被分配到属于该栈帧的一块空间。熟悉数据结构的人都知道,函数的嵌套调用、链式调用等都是一个不断入栈退栈的过程。为了节省操作时间和资源,当一个函数调用完成后,它的栈帧退栈时,只是相应的将栈顶指针进行移动,并没有将其刚刚占用的栈的空间清0。因此在下次再调用其他函数时,模块内auto类型变量被分配到的是一块记录了上次遗留数值的内存区。所以在模块内声明auto类型变量时,一定要记住它的初始化。

=================================================

3 存储类型关键字:extern3.1 作用域: 我们知道,C语言的编译是以文件为单位的。所以对于该文件中的全局变量来说,其作用域只是该文件。如果需要在其他文件中也使用该关键字,就需要用到extern关键字进行外部链接。3.2 生存期: 需要注意的是,进行外部链接的变量类型不能是模块内的局部变量,而应该是一个存储在静态存储区的变量。只有这样,在提供给外部链接的变量地址才能是一个固定值,而不是像局部变量那样可以随时改变变量地址。因此extern变量的生存期也是整个程序运行期间。

=================================================

4 存储类型关键字:register

4.1 作用域:register关键字是建议编译器将变量存放在一个寄存器中,一般用于频繁调用的变量,以提高代码的执行速度。register的用法和auto十分相似,它们都是用于的模块内部的局部变量声明,因此register的作用域是该函数。

4.2 生存期: register的运行期是该函数运行期间。

4.3 register和auto的区别

1)存放位置不同

register和auto都是用于模块内部局部变量的声明类型,它们都是在函数调用和退出时,即用即销毁,但它们的实际存储区域不同。

auto关键字位于内存中的堆栈区,虽然只有到函数执行时,才能确定它的具体变量地址,但是也是可以用&符号取出它的变量地址的。而register变量存放在寄存器中,寄存器的编址方式和内存的编址方式不属于一套体系。因此不能用&符号对寄存器进行操作

2)存放大小限制

寄存器的位数一般都与机器字长相关,要存放在一个寄存器中变量不能超过寄存器可以容纳的位数。比如:对于32位字长的机器来说,寄存器位数一般是32位,那么可以存一个32位的数据类型,比如int,它不能存储64位数据类型的数据,比如long类型;而auto类型变量就没有那么多限制,无非是32位拆成4个字节存储,64位拆成8个字节存储。

3)运行速度不同

register类型在CPU内部寄存器中,高速总线上传输,程序执行速度肯定比auto类型快。

总结:上面乱七八糟说了那么多,下面给出一张图作为本篇的结束(注:加括号的表示可缺省)。

如果觉得《C语言——变量篇(一)变量关键字static auto extern register》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。