C语言32个关键字_作用域修饰符

来源:互联网 发布:华为java面试题2016 编辑:程序博客网 时间:2024/06/08 18:03

变量的存储方式可分为“静态存储”和“动态存储”两种。

静态存储变量通常是在变量定义时就分定存储单元并一直保持不变,直至整个程序结束。

动态存储变量是在程序执行过程中,使用它时才分配存储单元,使用完毕立即释放。

典型的例子是函数的形式参数,在函数定义时并不给形参分配存储单元,只是在函数被调用时,才予以分配,调用函数完毕立即释放。如果一个函数被多次调用,则反复地分配、释放形参变量的存储单元。

从以上分析可知,静态存储变量是一直存在的,而动态存储变量则时而存在时而消失。我们又把这种由于变量存储方式不同而产生的特性称变量的生存期。生存期表示了变量存在的时间。生存期和作用域是从时间和空间这两个不同的角度来描述变量的特性,这两者既有联系,又有区别。一个变量究竟属于哪一种存储方式,并不能仅从其作用域来判断,还应有明确的存储类型说明。

在C语言中,对变量的存储类型说明有以下四种:

auto自动变量

register寄存器变量

extern外部变量

static静态变量

自动变量和寄存器变量属于动态存储方式,

外部变量和静态变量属于静态存储方式。

在介绍了变量的存储类型之后,可以知道对一个变量的说明不仅应说明其数据类型,还应说明其存储类型。因此变量说明的完整形式应为:存储类型说明符数据类型说明符变量名,变量名…;例如:

static int a,b;说明a,b为静态类型变量

auto char c1,c2;说明c1,c2为自动字符变量

static int a[5]={1,2,3,4,5};说明a为静整型数组

extern int x,y;说明x,y为外部整型变量

下面分别介绍以上四种存储类型:

一、自动变量的类型说明符为auto

这种存储类型是C语言程序中使用最广泛的一种类型。C语言规定,函数内凡未加存储类型说明的变量均视为自动变量,也就是说自动变量可省去说明符auto。在前面各章的程序中所定义的变量凡未加存储类型说明符的都是自动变量。例如:


void main(void)

{  

         int i,j,k;

        char c;

         ……

}

等价于:

{

          auto int i,j,k;

          auto char c;

……

}

自动变量具有以下特点:

1.自动变量的作用域仅限于定义该变量的个体内。在函数中定义的自动变量,只在该函数内有效。在复合语句中定义的自动变量只在该复合语句中有效。例如:

int kv(int a)

{

            auto int x,y;

           {

                       auto char c;

             } /*c的作用域*/

            ……

} /*a,x,y的作用域*/

2.自动变量属于动态存储方式,只有在使用它,即定义该变量的函数被调用时才给它分配存储单元,开始它的生存期。函数调用结束,释放存储单元,结束生存期。因此函数调用结束之后,自动变量的值不能保留。在复合语句中定义的自动变量,在退出复合语句后也不能再使用,否则将引起错误。例如以下程序:

main()

{ auto int a,s,p;

printf("\ninput a number:\n");

scanf("%d",&a);

if(a>0)

 {

          s=a+a;

          p=a*a;

}

printf("s=%d p=%d\n",s,p);

}

{

                 auto int a;

                printf("\ninput a number:\n");

                  scanf("%d",&a);

                 if(a>0)

                 {

                             auto int s,p;

                              s=a+a;

                               p=a*a;

                   }

                    printf("s=%d p=%d\n",s,p);

}

s,p是在复合语句内定义的自动变量,只能在该复合语句内有效。而程序的第9行却是退出复合语句之后用printf语句输出s,p的值,这显然会引起错误。

3.由于自动变量的作用域和生存期都局限于定义它的个体内(函数或复合语句内),因此不同的个体中允许使用同名的变量而不会混淆。即使在函数内定义的自动变量也可与该函数内部的复合语句中定义的自动变量同名。例5.14表明了这种情况。

[例5.14]

main()

{

auto int a,s=100,p=100;

printf("\ninput a number:\n");

scanf("%d",&a);

if(a>0)

{

auto int s,p;

s=a+a;

p=a*a;

printf("s=%d p=%d\n",s,p);

}

printf("s=%d p=%d\n",s,p);

}

本程序在main函数中和复合语句内两次定义了变量s,p为自动变量。按照C语言的规定,在复合语句内,应由复合语句中定义的s,p起作用,故s的值应为a+ a,p的值为a*a。退出复合语句后的s,p应为main所定义的s,p,其值在初始化时给定,均为100。从输出结果可以分析出两个s和两个p虽变量名相同,但却是两个不同的变量。

4.对构造类型的自动变量如数组等,不可作初始化赋值。

二、外部变量外部变量的类型说明符为extern

在前面介绍全局变量时已介绍过外部变量。这里再补充说明外部变量的几个特点:

1. 外部变量和全局变量是对同一类变量的两种不同角度的提法。全局变是是从它的作用域提出的,外部变量从它的存储方式提出的,表示了它的生存期。

2. 当一个源程序由若干个源文件组成时, 在一个源文件中定义的外部变量在其它的源文件中也有效。例如有一个源程序由源文件F1.C和F2.C组成: F1.C

int a,b; /*外部变量定义*/

char c; /*外部变量定义*/

main()

{

……

}

F2.C

extern int a,b; /*外部变量说明*/

extern char c; /*外部变量说明*/

func (int x,y)

{

……

}

在F1.C和F2.C两个文件中都要使用a,b,c三个变量。在F1.C文件中把a,b,c都定义为外部变量。在F2.C文件中用extern把三个变量说明为外部变量,表示这些变量已在其它文件中定义,并把这些变量的类型和变量名,编译系统不再为它们分配内存空间。 对构造类型的外部变量, 如数组等可以在说明时作初始化赋值,若不赋初值,则系统自动定义它们的初值为0。

在声明局部变量时,默认均是 auto,这类变量都是动态分配存储空间的,数据存储在动态存储区中。

const定  义不可更改的常量值

const int a;

const int *p;

int const *p;

int* const p;

int const * const p;

你需要了解一下:

本质:const在谁后面谁就不可修改,const在最前面则将其后移一位即可,二者等效

static      定义静态变量

1)在函数体内,一个被声明为静态的变量,使用关键字 static 将局部变量指定为“静态局部变量”,这样在函数调用结束后不消失而保留原值,即占用的存储单元不释放,在下一次函数调用时,该变量已有值就是上次函数调用结束时的值。

2)在模块内(静态全局变量)(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。

3)在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用。

register    CPU内部寄存的变量

在声明动态局部变量或者函数形参时,可将变量声明为register,这样编译系统就会为变量分配一个寄存器而不是内存空间,通过这种方式可提升对某些局部变量频繁调用的程序的性能。(寄存器运算速度远高于内存)

extern      在其它程序模块中说明了全局变量

用于扩展全局变量的作用域,比如如果函数想引用一个外部变量,但该外部变量在该函数后定义,那么这个函数需要使用 extern 来声明变量,这样才能使用在该函数后面定义的全局变量。此外,extern 还可以在多文件的程序中声明外部变量。

全局变量 :在函数外定义的变量,可以为本源文件中其它函数所公用,有效范围为从定义变量的位置开始到本源文件结束,这种类型的变量就称为“全局变量”。

原创粉丝点击