【C】C语言函数中的变量(包括:作用域、存储类型)

局部变量和全局变量

C语言中变量按其作用域分,可分为局部变量和全局变量,具体的解释为:

  • 局部变量(内部变量):在定义它的函数内有效,但是函数返回后失效;
  • 全局变量(外部变量):在所有源文件内均有效。在同源文件的函数中使用使用全局变量,需要将全局变量提前声明;同时在不包含全局变量定义的不同源文件需要用extern关键字再次声明。

关于C语言全局变量和局部变量,还有几个注意点:

  • 如果在该函数内定义了一个与之前定义的全局变量同名的变量,那么该同名局部变量就会在函数内部屏蔽全局变量的影响。即当局部变量与全局变量同名时,在局部变量的作用范围之内,全局变量不起作用。局部变量优先原则
  • 全局变量是有默认值的(引用类型的变量默认值都是null,基本类型的变量默认值则不一样,int型变量默认值是0),但是局部变量没有默认值;
  • 全局变量可以在函数外定义并初始化,但不能进行赋值操作。这是什么意思呢?我们看一下:
#include<stdio.h>

int a = 0;

int main()
{
	printf("%d\n", a);

	return 0;
}

此时程序运行通过,程序中a为全局变量,在函数外进行定义并初始化。

#include<stdio.h>

int a = 0;
a = 1;

int main()
{
	printf("%d\n", a);

	return 0;
}

此时程序运行错误。全局变量在函数体外只能进行初始化,不能进行赋值运算。

#include<stdio.h>

int a;
a = 1;

int main()
{
	printf("%d\n", a);

	return 0;
}

此时程序运行通过,C语言执行过程中,对代码进行了优化,把程序2中的int a;a=1;优化为一句话:int a=1;这就是初始化。

 

变量的存储类型

C语言中变量按其存在的时间(即生存期)分,可分为动态存储变量和静态存储变量。

  • 动态存储变量:当程序运行进入定义它的函数或复合语句时才被分配存储空间,程序运行结束离开此函数或复合语句时,所占用的内存空间被释放。这是一种节省内存空间的存储方式;
  • 静态存储变量:在程序运行的整个过程中,始终占用固定的内存空间,直到程序运行结束,才释放占用的内存空间。静态存储类别的变量被存放在空间的静态存储区。

在C语言程序运行时,占用的内存空间被分成三部分:程序代码区、静态存储区、动态存储区

程序运行中的数据分别存储在静态存储区和动态存储区。静态存储区用来存放程序运行期间所占用的固定存储单元的变量,如全局变量等;动态存储区用来存放不需要长期占用内存的变量,如局部变量等。

变量的存储类型具体来说分成4种:自动类型(auto)、寄存器类型(register)、静态类型(static)、外部类型(extern)。其中,自动类型、寄存器类型的变量属于动态变量,静态类型、外部类型属于静态变量。

自动变量(auto)

自动类型是C语言程序中使用最广泛的一种类型。函数中的局部变量,如果不专门声明为static存储类型,都是动态分配存储空间的,数据存储在动态存储区。函数中的形参和函数中定义的变量都属于此类。在调用这些函数时,系统会给它们分配存储空间,在函数调用结束后就自动释放这些存储空间。

  • C语言规定:函数内凡未加存储类型说明的变量均视为自动变量,也就是说,自动变量可省略说明符auto,说明符auto不写则隐含表示该变量为自动存储类型的。
  • 对于自动变量来说,如果不赋初值,它的值是一个不确定的值。

自动变量的一般形式为:

{
    (auto) 类型 变量名;
}

静态变量(static)

静态变量存储在静态存储区,用static关键字来声明。属于静态存储方式,又可分成静态全局变量和静态局部变量。

C语言规定:静态变量(包括静态局部变量、静态全局变量)有默认值,int型等于0,float型等于0.0,char型等于'\0'。而自动变量和寄存器变量没有默认值,是随机值。

  • 静态局部变量:只在定义它的函数内有效。只是程序仅分配一次内存,函数返回后,该变量不会消失,只有程序结束后才会释放内存;
  • 静态全局变量:只在定义它的文件内有效,且生存期在整个程序运行期间。

静态变量的一般形式为:

static 类型 变量名;
{
    static 类型 变量名;
}
几个变量的区别
变量类型存储类型存储区域作用域
局部变量自动变量(auto)动态存储区定义它的函数
静态局部变量静态变量(static)静态存储区定义它的函数
全局变量外部变量(extern)静态存储区所有的源文件
静态全局变量静态变量(static)静态存储区定义它的源文件

static关键字的作用:

  • 在函数体中,一个被声明为静态的变量在这一函数被调用过程中只会被分配一次内存,且整个运行期间不会重新分配;
  • 在函数体外、某个源文件内,一个被声明为静态的变量只可被该源文件内的所有函数访问,但不能被其他源文件的函数访问。它是一个本地的全局变量;
  • 在某个源文件内,一个被声明为静态的函数仅仅只可以被这个源文件的其它函数调用。也就是说,这个函数被限制在声明它的源文件的本地范围之内使用。

也就是说,static的作用主要体现在两点上:

  • 对于局部变量而言,加上static,就将数据保存到静态存储区,仅分配一次内存,生存期大大加强(改变存储区域);
  • 对于全局变量而言,由于本身已经在静态存储区,加上static,就将变量作用域限制到定义它的源文件内(改变作用域)。

对于函数也是一样,限制范围。而不限制全局变量和函数范围的时候,其他源文件需要引用的时候,都需要extern关键字。

寄存器变量(register)

除了常用的自动变量和静态变量之外,C语言还提供了一种帮助程序员利用CPU寄存器的方法。使用关键字register来声明局部变量时,该变量即称为寄存器变量。寄存器变量是动态局部变量,存放在CPU的寄存器或动态存储区中,该类变量的作用域、生存期和自动变量相同。如果没有存放在寄存器中,就按自动变量处理。

寄存器变量的好处是:寄存器的存储速度比内存快得多。但是由于现在编译系统的优化,使得编译器可以自动识别频繁使用的变量,并自动将其存储在寄存器中,故而现在寄存器变量的定义是不必要的。

寄存器变量的一般形式为:

{
    register 类型 变量名;
}

register由于是在寄存器(动态存储区)中,所以,寄存器变量不可能同时又是全局变量或者静态变量!

外部变量(extern)

外部变量(即全局变量)是在函数的外部定义的,它的作用域为从变量定义处开始,到本程序文件的末尾。如果在定义点之前的函数想引用该外部变量,则应该在引用之前用关键字extern对该变量作“外部变量声明”。表示该变量是一个已经定义的外部变量。有了此声明,就可以从“声明”处起,合法地使用该外部变量。

在一个文件中定义的全局变量默认为外部的,即关键字extern可以省略,但如果在其他的文件中使用这个文件定义的全局变量,则必须在使用前用extern进行外部声明。

外部变量的一般形式为:

extern 类型 变量名;

extern关键字的作用:

  • 在本文件范围内扩展外部变量的作用域;
  • 将外部变量作用域扩展到其他源文件中。

解释:当编译开始的时候,编译器总能从使用extern进行外部变量声明的地方开始在本文件中查找外部变量的定义。如果外部变量的定义在本文件中找到,那么外部变量的作用域就在本文件中进行扩展;如果本文件中没有找到,编译器就会去其他文件中查找外部变量的定义。这时,变量的作用域就扩展到了其他文件。

 

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 程序猿惹谁了 设计师:上身试试 返回首页