变量的作用域

变量的作用域
变量的作用域

变量的作用域

关键词:作用域全局变量局部变量静态变量外部变量常量 volatile变量

作用域:

作用域规则告诉我们一个变量的有效范围,它在哪儿创建,在哪儿销毁(也就是说超出了作用域)。变量的有效作用域从它的定义点开始,到和定义变量之前最邻近的开括号配对的第一个闭括号。也就是说,作用域由变量所在的最近一对括号确定。

全局变量:

全局变量是在所有函数体的外部定义的,程序的所在部分(甚至其它文件中的[url=]代码[/url])都可以使用。全局变量不受作用域的影响,问题可以使用的(也就是说,全局变量的生命期一直到程序的结束)。如果在一个文件中使用extern关键字来声明另一个文件中存在的全局变量,那么这个文件可以使用这个数据。

局部变量:

局部变量出现在一个作用域内,它们是局限于一个函数的。局部变量经常被称为自动变量,因为它们在进入作用域时自动生成,离开作用域时自动消失。关键字auto可以显式地说明这个问题,但是局部变量默认为auto,所以没有必要声明为auto。

寄存器变量

寄存器变量是一种局部变量。关键字register告诉编译器“尽可能快地访问这个变量”。加快访问速度取决于现实,但是,正如名字所暗示的那样,这经常是通过在寄存器中放置变量来做到的。这并不能保证将变置在寄存器中,甚至也不能保证提高访问速度。这只是对编译器的一个暗示。使用register变量是有限制的。不可能得到或计算register 变量的地址。register变量只能在一个块中声明(不可能有全局的或静态的register 变量)。然而可以在一个函数中(即在参数表中)使用register变量作为一个形式参数。一般地,不应当推测编译器的优化器,因为它可能比我们做得更好。因此,最好避免使用关键字register。

静态变量

关键字static有一些独特的意义。通常,函数中定义局部变量在函数中作用域结束时消失。当再次调用这个函数时,会重新创建变量的存储空间,其值会被重新初始化。如果想使局部变量的值在程序的整个生命期里仍然存在,我们可以定义函数的局部变量为

static(静态的),并给它一个初始化。初始化只在函数第一次调用时执行,函数调用之间变

量的值保持不变,这种方式,函数可以“记住”函数调用之间的一些信息片断。我们可能奇怪为什么不使用全局变量。static变量的优点是在函数范围之外它是不可用的,所以它不可能被轻易改变。这会使错误局部化。static函数与普通函数有什么区别:static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝

外部变量

extern告诉编译器存在着一个变量和函数,即使编译器在当前的文件中没有看到它。这个变量或函数可能在一个文件或者在当前文件的后面定义。例如extern int i;编译器会知道i肯定作为全局变量存在于某处。当编译器看到变量i的定义时,并没有看到别的声明,所以知道它在文件的前面已经找到了同样声明的i

常量

const告诉编译器这个名字表示常量,不管是内部的还是用户定义的数据类型都可以定义为const。如果定义了某对象为常量,然后试图改变它,编译器将会产生错误。在C++中一个const必须有初始值。

volatile变量

限定词const告诉编译器“这是不会改变的”(这就是允许编译器执行额外的优化);而限定词volatile则告诉编译器“不知道何时变化”,防止编译器依据变量的稳定性作任何优化。

变量的作用域与存储类别&&变量的生存期——天擎国际

变量的作用域与存储类别(变量的作用域——变量的生存期) 变量的作用域 ——局部变量和全局变量 变量的生存期 ——静态存储类别和动态存储类别(注意区别存储类型和函数类型) 变量的作用域 一、局部变量 定义:在一个函数内部定义的变量是内部变量,它只在本函数范围内有效。 二、全局变量 定义:在函数之外定义的变量称为外部变量,或全局变量。它可为本文件中其他函数所共用。有效范围为从定义变量的位置开始到本源文件结束。 注意: 全局变量在程序的全部执行过程中都占有存储单元,而不是仅在需要时才开辟单元。 它使函数的通用性降低,因函数在执行时要依赖于其所在的外部变量。 降低了程序的清晰性。 在同名局部变量作用的范围内,外部变量被“屏蔽”。 变量的生存期

一、动态存储方式与静态存储方式 静态存储:在程序运行期间分配固定的存储空间的方式。 动态存储:在程序运行期间根据需要进行动态的分配存储空间的方式。 静态存储区:存储空间的分配在编译阶段进行,且存于其中的数据对象相对于程序的执行是永久的。 动态存储区:存储空间的分配是在程序的运行过程中进行的。 二、auto变量 调用函数时系统自动分配存储空间,在函数调用结束时自动释放这些存储空间,称这类局部变量为自动变量。 用关键字auto作存储类别的声明。它也可省。 三、用static声明局部变量 静态的 局部的 说明: 静态局部变量属于静态存储类别,在静态存储区内分配单元。在程序整个运行期都不释放。 自动变量属于动态存储类别,在动态存储区内分配单元,函数调用结束后即释放。 静态局部变量在编译时赋初值,以后每次函数调用时不再重新赋初值 ... .......而只是保留上次函 数调用结束时 ......的值。 自动变量赋初值,不是在编译时进行的,而是在函数调用时进行,每调用一次函数重新给一次初值。 静态局部变量,如不赋初值,编译时自动赋初值0 或空字符。 自动变量,如不赋初值,它的值是一个不确定的值。 虽然静态局部变量在函数调用结束后仍然存在,但其他函数不能引用。 一般在下列情况时,使用局部静态变量: 1、需要保留函数上一次调用结束时的值时; 2、如果初始化后,变量只被引用而不改变其值时。 四、register变量 说明: 1、只有局部自动变量和形参可作为register变量。 2、不能定义任意多个寄存器变量。 3、局部静态变量不能定义为寄存器变量。 五、用extern声明外部变量 在一个文件内声明外部变量 例:main( ) { extern A; /*外部变量声明*/ printf(“%d”,A); }

变量的作用域和生存期

变量的作用域局部变量和全局变量 在函数和复合语句内定义的变量,只在本函数或复合语句范围内有效(从定义点开始到函数或复合语句结束),他们称为内部变量或局部变量。 在函数之外定义的变量是外部变量,也称为全局变量(或全程变量)。 如果在一个函数中全局变量和局部变量同名,则在局部变量的作用范围内,外部变量被“屏蔽”,即他不起作用,此时局部变量是有效的。 全局变量的作用是增加函数间数据联系的渠道。 虽然全局变量有以上优点,但建议不必要时不要使用全局变量,因为全局变量在程序的全部执行过程中都占用存储单元,而不是仅在需要时才开辟单元。 在程序设计时,对模块的划分要求:内聚性强,与其他模块的耦合性弱,这样便于程序的移植,可读性强。 变量的生存期 变量的存储方式分为两种:静态存储方式和动态存储方式。 静态存储方式是指在程序与性能期间由系统在静态存储区分配存储空间的方式,在程序运行器件不释放;而动态存储方式则是在函数调用期间根据需要在动态存储区分配存储空间的方式。这就是变量的存储区别。 Auto----声明自动变量 函数中的形参和在函数中定义的变量都属于此类。在调用这些函数时,系统给这些变量分配存储空间,函数调用结束时就自动释放这些存储空间。因为这类局部变量称为自动变量(auto 变量)。关键字auto作为存储类别的声明。 Auto可省略 Static-----声明静态变量 希望函数中的变量的局部变量的值在函数调用结束后不消失而继续保留原值,即其占用的存储单元不释放,在下一次该函数调用时,该变量已有值,就是上一次函数调用结束时的值。这时就用关键字static指定该局部变量为“静态存储变量”。 对静态局部变量的说明 静态局部变量属于静态存储类别,在静态存储区内分配存储单元,在程序整个运行期间都不释放。而自动变量(即动态局部变量)属于动态存储类别,占胴体啊存储区空间而不占静态存储区空间,函数调用结束后即释放。 对静态局部变量是在编译时赋初值的,即只赋初值一次,在以后每次调用函数时不再重新赋初值而只是保留上次函数调用结束时的值。自动变量赋初值是在函数调用时进行的。 对静态局部变量来说,编译时自动赋初值0或空字符。而对自动变量来说,如果不赋值则他的值是一个不确定的值。 Registic--声明寄存器变量 这种变量一般不用,只需了解就可以了。 Extern-----声明外部变量的作用范围 如果一个程序中有两个文件,在两个文件中都要用到同一个外部变量Num,不能分别在两个文件中各自定义一个外部变量Num,否则在进行程序的连接时会出现“重复定义”的错误。正确的做法:在人一个文件中定义外部变量Num,而在另一个文件中用extern对Num作外部变量声明,即extern Num.

变量的生命周期与作用域

作用域和生存周期是完全不同的两个概念。作用域可以看作是变量的一个有效范围,就像网游中的攻击范围一样;生存周期可以看成是一个变量能存在多久,能在那些时段存在,就像网游中的魔法持续时间……简单的以一个局部变量来举个例子:在main函数中声明了变量a,那么a的作用域就是main函数内部,脱离了main函数,a就无法使用了,main函数之外的函数或者方法,都无法去使用a。那么a的生存周期是指a在那些时候存在,具体到这个例子,a什么时候存在,要取决于main函数,或者说,main函数只要被调用,且调用没有完成,那么a就将存在。除此以外的情况,a都将被释放。生存周期也可以理解为从声明到释放的之间的时间。变量具体可以分为全局变量、静态全局变量、静态局部变量和局部变量。按存储区域分:全局变量、静态全局变量和静态局部变量都存放在内存的全局数据区,局部变量存放在内存的栈区按作用域分:全局变量在整个工程文件内都有效;静态全局变量只在定义它的文件内有效;静态局部变量只在定义它的函数内有效,只是程序仅分配一次内存,函数返回后,该变量不会消失;局部变量在定义它的函数内有效,但是函数返回后失效。全局变量和静态变量如果没有手工初始化,则由编译器初始化为0。局部变量的值不可知。 总的分为局部变量和全局变量:局部变量又可分为动态局部变量(没特殊声明的变量一般都为动态局部变量)和静态局部变量(用static关键字声明的变量如:static int a;);两者的区别在于:静态的局部变量生存期比动态的局部变量来的长,动态的局部变量的生存期为所定义的范围内,如在函数内定义的,函数结束,变量也跟着结束,变量的值不会保存下来。而静态变量的生存期为整个源程序(也可说是一个文件,不同环境不同称呼)。而两者的作用域是一样。只能在定义他的函数内起作用,离开了这个函数就不起作用了。全局变量:在函数之外定义的变量称为全局变量。全局变量可以为本文件中其他函所共用(作用域),它的有效范围(生存期)从定义变量开始到文件结束。如果在同一个源文件中,外部变量与局部变量同名,则在局部变量的作用范围内,外部变量被“屏蔽”,即全局变量不起作用。下面来看一个例子:#include"stdio.h"int d=1; //声明一个全局变量int fun(int p) { static int d=5; //定义一个静态局部变量d初值为5 //第二次调用时没有执行此行d=d+p; //此时局部变量d的值为9,(第一次调用)//第二次调用是局部变量d 的值为13,因为上一次执行完后d的值为9,printf("%d",d); //第一次输出为9,//第二次输出13}void main(){ int a=3; d=d+a; //此时d的值为4;a变量的值为3,全局变量d的值为1。for(i=0;i<2;i++) fun(d); //此处的d值为4,传送给形参p,再一次调用时还是将4传给开参p printf("d=%d",d); //输出d的值为4.此处的d为全局变量。} 看以上内容时,你先把程序看一篇,然后把会值代进去远算,每一次看注释时在同一行中只要看到第二个”//“时结束.第2个“//”为第二次调用时看的。以上内容有一点乱,但是希望可以帮助到你...88有什么不明白可以再问!答案补充 看程序时注释行不要选先看。本程序一共调用fun函数两次,两次实参的值都为4.

(十二)变量的作用域和存储类型

一、作用域和生存期 C程序的标识符作用域有三种:局部、全局、文件。标识符的作用域决定了程序中的哪些语句可以使用它,换句话说,就是标识符在程序其他部分的可见性。通常,标识符的作用域都是通过它在程序中的位置隐式说明的。 1.局部作用域 前面各个例子中的变量都是局部作用域,他们都是声明在函数内部,无法被其他函数的代码所访问。函数的形式参数的作用域也是局部的,它们的作用范围仅限于函数内部所用的语句块。 void add(int); main() { int num=5; add(num); printf(%d\n,num); /*输出5*/ } void add(int num) { num++; printf(%d\n,num); /*输出6*/ } 上面例子里的两个num变量都是局部变量,只在本身函数里可见。前面我们说了,在两个函数出现同名的变量不会互相干扰,就是这个道理。所以上面的两个输出,在主函数里仍然是5,在add()函数里输出是6。 2.全局作用域 对于具有全局作用域的变量,我们可以在程序的任何位置访问它们。当一个变量是在所有函数的外部声明,也就是在程序的开头声明,那么这个变量就是全局变量。 void add(int); int num; main() { int n=5; add(n); printf(%d\n,num); /*输出6*/ } void add(num) /*形式参数没有指定类型*/

num++; printf(%d\n,num); /*输出6*/ } 上面的main()和add()里面,并没有声明num,但是在最后输出的时候却要求输出num,这是由于在程序的开始声明了num是全局变量,也就是在所有函数里都可以使用这个变量。这时候一个函数里改变了变量的值,其他函数里的值也会出现影响。上面的例子输出都是6,因为在add()函数里改变了num的值,由于num是全局变量,就好象它们两个函数共用一个变量,所以在main()函数里的num也随之改变了。 3.文件作用域 在很多C语言书上,都没有说明文件作用域,或者只是略微的提到,其实文件作用域在较大程序中很有作用(在多文件系统中)。文件作用域是指外部标识符仅在声明它的同一个转换单元内的函数汇总可见。所谓转换单元是指定义这些变量和函数的源代码文件(包括任何通过#include指令包含的源代码文件)。static存储类型修饰符指定了变量具有文件作用域。 static int num; static void add(int); main() { scanf(%d,&num); add(num) printf(%d\n,num); } void add(num) { num++; } 上面的程序中变量num和函数add()在声明是采用了static存储类型修饰符,这使得它们具有文件作用域,仅爱定义它们的文件内可见。 由于我们提到的大多数程序都只有一个编译文件组成,所以这种写法没有实际意义。但是实际工程上的文件有很多,它们不是由一个人写成的,由很多人共同完成,这些文件都是各自编译的,这难免使得某些人使用了一样的全局变量名,那么为了以后程序中各自的变量和函数不互相干扰,就可以使用static修饰符,这样在连接到同一个程序的其他代码文件而言就是不可见的。 二、变量存储类型 前面我们说了,声明变量时用如下类似的形式: int num; float total;

变量作用域

数据的存储类型 一、变量的作用域 变量的作用域是指变量有效性的范围,与变量定义的位置密切相关,作用域是从空间这个角度来描述变量的,按照作用域的不同,变量可分为局部变量和全局变量。 1、局部变量 在函数(或代码块)内部定义的变量,也称为内部变量,局部变量只能在定义它的函数(或代码块)内使用,其他函数均不能使用,局部变量的作用域,限于说明它的代码块内:从说明的地方开始至所在的代码块结束。注意,在同一个作用域内,不允许有同名的变量。 例如:在同一个main()函数中,定义了三个数据类型和变量名均相同的局部变量i。在访问这些变量i中,他们不会混淆,它们是三个不同的局部变量。它们各有自己的作用域。 代码如下: #include void main() { int i=10; printf("The first i is %d\n",i); printf("Enter a positive or negative number: "); scanf("%d",&i); printf("In main() i=%d\n",i); if(i>0) { int i=-10; printf("In if i is %d\n",i); } else { int i=20; printf("In else i is %d\n",i); } printf("The i in main() still is %d\n",i); return; } 运行结果: 2、全部变量 作用域是从定义点开始直到程序文件结束的变量,称为全局变量。全局变量在程序的整个运

行过程中,都占用存储单元。在一个函数中改变了全局变量的值,其他函数可以共享。全局变量相当于起到在函数间传递数据的作用。 例如:求一元二次方程的根:ax2 + bx + c =0 代码如下: #include #include float X1,X2,p,q,d; //定义全局变量 void greater_than_zero(float,float); //函数声明 void equal_to_zero(float,float); void smaller_than_zero(float,float); void main() { float a,b,c; //定义局部变量 printf("Enter a,b,c: "); scanf("%f%f%f",&a,&b,&c); d=b*b-4*a*c; if(d>0) { greater_than_zero(a,b); printf("X1 = %5.2f\tX2 = %5.2f\n",X1,X2); } else if(d==0) { equal_to_zero(a,b); printf("X1 = X2 = %5.2f\n",X1); } else { smaller_than_zero(a,b); printf("X1 = %5.2f+%5.2fi\n",p,q); printf("X2 = %5.2f-%5.2fi\n",p,q); } return; } void greater_than_zero(float x,float y) { X1=(-y+sqrt(d))/(2*x); X1=(-y-sqrt(d))/(2*x); return;

C语言变量作用域和生存期

C语言变量作用域和生存期 C语言的强大功能之一是可以灵活地定义数据的存储方式。C语言从两个方面控制变量的性质:作用域(scope)和生存期(lifetime)。作用域是指可以存取变量的代码范围,生存期是指可以存取变量的时间范围。 作用域有三种: 1.extern(外部的)这是在函数外部定义的变量的缺省存储方式。extern变量的作用域是整个程序。 2.static(静态的)在函数外部说明为static的变量的作用域为从定义点到该文件尾部;在函数内部说明为static的变量的作用域为从定义点到该局部程序块尾部。 3.auto(自动的)这是在函数内部说明的变量的缺省存储方式。auto变量的作用域为从定义点到该局部程序块尾部。 变量的生存期也有三种,但它们不象作用域那样有预定义的关键字名称。 1.第一种是extern和static变量的生存期,它从main()函数被调用之前开始,到程序退出时为止。 2.第二种是函数参数和auto变量的生存期,它从函数调用时开始,到函数返回时为止。 3.第三种是动态分配的数据的生存期,它从程序调用malloc()或calloc()为数据分配存储空间时开始,到程序调用free()或程序退出时为止。 作用域和生存周期是完全不同的两个概念。作用域可以看作是变量的一个有效范围,就像网游中的攻击范围一样;生存周期可以看成是一个变量能存在多久,能在那些时段存在,就像网游中的魔法持续时间…… 简单的以一个局部变量来举个例子: 在main函数中声明了变量a,那么a的作用域就是main函数内部,脱离了main函数,a 就无法使用了,main函数之外的函数或者方法,都无法去使用a。那么a的生存周期是指a 在那些时候存在,具体到这个例子,a什么时候存在,要取决于main函数,或者说,main 函数只要被调用,且调用没有完成,那么a就将存在。除此以外的情况,a都将被释放。 生存周期也可以理解为从声明到释放的之间的时间。 变量具体可以分为全局变量、静态全局变量、静态局部变量和局部变量。 按存储区域分:全局变量、静态全局变量和静态局部变量都存放在内存的全局数据区,局部变量存放在内存的栈区 按作用域分:全局变量在整个工程文件内都有效;静态全局变量只在定义它的文件内有效;静态局部变量只在定义它的函数内有效,只是程序仅分配一次内存,函数返回后,该变量不会消失;局部变量在定义它的函数内有效,但是函数返回后失效。 全局变量和静态变量如果没有手工初始化,则由编译器初始化为0。局部变量的值不可知。

C语言的变量的作用域和生存期

C语言的变量的作用域和生存期 一、c程序存储空间布局 C程序一直由下列部分组成: 1)正文段——CPU执行的机器指令部分;一个程序只有一个副本;只读,防止程序由于意外事故而修改自身指令; 2)初始化数据段(数据段)——在程序中所有赋了初值的全局变量,存放在这里。 3)非初始化数据段(bss段)——在程序中没有初始化的全局变量;内核将此段初始化为0。 4)栈——增长方向:自顶向下增长;自动变量以及每次函数调用时所需要保存的信息(返回地址;环境信息)。 5)堆——动态存储分。 |-----------| | | |-----------| | 栈 | |-----------| | | | | /|/ | | | | | | /|/ | | | | |-----------| | 堆 | |-----------| | 未初始化 | |-----------| | 初始化 | |-----------| | 正文段 | |-----------| 二、面向过程程序设计中的static 1. 全局静态变量 在全局变量之前加上关键字static,全局变量就被定义成为一个全局静态变量。 1)内存中的位置:静态存储区(静态存储区在整个程序运行期间都存在) 2)初始化:未经初始化的全局静态变量会被程序自动初始化为0(自动对象的值是任意的,除非他被显示初始化) 3)作用域:全局静态变量在声明他的文件之外是不可见的。准确地讲从定义之处开始到文件结尾。

看下面关于作用域的程序: //teststatic1.c void display(); extern int n; int main() { n = 20; printf("%d/n",n); display(); return 0; } //teststatic2.c static int n; //定义全局静态变量,自动初始化为0,仅在本文件中可见void display() { n++; printf("%d/n",n); } 文件分别编译通过,但link的时候teststatic1.c中的变量n找不到定义,产生错误。 定义全局静态变量的好处: <1>不会被其他文件所访问,修改 <2>其他文件中可以使用相同名字的变量,不会发生冲突。 2. 局部静态变量 在局部变量之前加上关键字static,局部变量就被定义成为一个局部静态变量。 1)内存中的位置:静态存储区 2)初始化:未经初始化的全局静态变量会被程序自动初始化为0(自动对象的值是任意的,除非他被显示初始化) 3)作用域:作用域仍为局部作用域,当定义它的函数或者语句块结束的时候,作用域随之结束。 注:当static用来修饰局部变量的时候,它就改变了局部变量的存储位置,从原来的栈中存放改为静态存储区。但是局部静态变量在离开作用域之后,并没有被销毁,而是仍然驻留在内存当中,直到程序结束,只不过我们不能再对他进行访问。 当static用来修饰全局变量的时候,它就改变了全局变量的作用域(在声明他的文件之外是不可见的),但是没有改变它的存放位置,还是在静态存储区中。 3. 静态函数 在函数的返回类型前加上关键字static,函数就被定义成为静态函数。

相关文档
最新文档