c语言全局变量和局部变量问题汇总

来源:互联网 发布:淘宝哪家女装店好 编辑:程序博客网 时间:2024/06/05 20:56

1、局部变量能否和全局变量重名?
答:能,局部会屏蔽全局。要用全局变量,需要使用”::”
局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量。对于有些编译器而言,在同一个函数内可以定义多个同名的局部变量,比如在两个循环体内都定义一个同名的局部变量,而那个局部变量的作用域就在那个循环体内。
2、如何引用一个已经定义过的全局变量?
答:extern
可以用引用头文件的方式,也可以用extern关键字,如果用引用头文件方式来引用某个在头文件中声明的全局变理,假定你将那个变写错了,那么在编译期间会报错,如果你用extern方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错。
3、全局变量可不可以定义在可被多个.C文件包含的头文件中?为什么?
答:可以,在不同的C文件中以static形式来声明同名全局变量。
可以在不同的C文件中声明同名的全局变量,前提是其中只能有一个C文件中对此变量赋初值,此时连接不会出错
4、static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别?
全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式,静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。
从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。
static函数与普通函数作用域不同,仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件
static全局变量与普通的全局变量有什么区别:static全局变量只初使化一次,防止在其他文件单元中被引用;
static局部变量和普通局部变量有什么区别:static局部变量只被初始化一次,下一次依据上一次结果值;
static函数与普通函数有什么区别:static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝.
5、程序的局部变量存在于(堆栈)中,全局变量存在于(静态区 )中,动态申请数据存在于( 堆)中。

  变量可以在程序中三个地方说明: 函数内部、函数的参数定义中或所有的函数外部。根据所定义位置的不同, 变量可分为局部变量、形式参数和全程变量。从空间角度来看,变量可以分为全局变量和局部变量,而从时间角度来分的 可以有静态存储变量和动态存储变量之分。

一。全局变量和局部变量

1。局部变量

他是 指在函数内部定义的变量 作用域为定义局部变量的函数 也就是说他只能在定义他的函数中使用

最值得注意的是 只有在程序执行到定义他的模块时才能生成,一旦执行退出该模块则起变量消失

eg.

func ()

{
int x; 局部变量x的作用域 很明确
……
}

2。全局变量

在程序执行的过程中一直有效

eg.

int x=1;

func ()

{
x=x+1;

}

func1 ()

{
x=x-1;

}

main ()

{

}
由此不难看出整型x的作用范围

对于全局变量 如果在定义的时候不做初始化 则系统将自动为起赋值 数值型为0

字符型为空’/0’

全局变量的弊端 增加内存开销 降低函数的通用性

定义全局变量时 理想的位置是在文件的开头 当这些函数以及同一个程序中的其他源程序文件中的某些函数需要使用该全局变量时 在函数内部对该变量使用extern 加以说明 说明他是外部的

(这里还要做详细的讲解)

eg.

main ()

{
extern int a,b;
printf (“mIn is %d/n”,min(a,b));
}

int a=1,b=2;
int min (x,y)
int x,y;
{
int z;
z=x

动态变量存放在堆区,函数代码放在代码区。

栈区是普通的栈数据结构,遵循LIFO后进先出的规则,局部变量安排在那里是ASM时就规定的,这样可以在一个函数结束后平衡堆栈,操作简单,效率高

堆(动态区)在这里应当叫堆栈(不要和数据结构中的堆搞混)是程序在编译时产生的一块用于产生动态内存分配使用的块,操作比较栈要麻烦许多,在分配时要判断最优的地址(防止产生无用的内存碎片(由于屡次的NEW和DELETE产生的夹在两块使用中内存中的空余小内存(不容易被分配))),分配和回收时的效率比栈低多了

栈是系统提供的功能,特点是快速高效,缺点是有限制,数据不灵活;而栈是函数库提供的功能,特点是灵活方便,数据适应面广泛,但是效率 >有一定降低。栈是系统数据结构,对于进程/线程是唯一的;堆是函数库内部数据结构,不一定唯一。不同堆分配的内存无法互相操作。栈空间分静态分配和动态分配两种。静态分配是编译器完成的,比如自动变量(auto)的分配。动态分配由alloca函数完成。栈的动态分配无需释放(是自动的),也就没有释放函数。为可移植>的程序起见,栈的动态分配操作是不被鼓励的!堆空间的分配总是动态的,虽然程序结束时所有的数据空间都会被释放回系统,但是精确的申请内存/ 释放内存匹>配是良好程序的基本要素。

这是我对堆与栈收藏内容~

堆是程序员管理的,栈是系统管理的.


—————————————————————

另外关于静态和全局的一些问题:
静态变量的特点:
1、 一次存储:静态局部变量只被初始化一次,下一次初始化根据上一次的结果值,有点类似于c++中类的静态成员变量,即无论该类型生成多少个实例对象,所有的对象共用一个静态变量,到这里就是无论这个函数调用多少次,该静态变量只初始化一次,并没有因为超出其生存期而被销毁,只是外部不可见而已,用个例子说明之:

void fun1( int v )
{
static int value = v;
static int value = v;
}
int main( int arc, char *args[ ])
{
fun1( 50 );
fun1( 100 );
}
执行的结果是:value : 50 value : 50
说明在第二次调用fun1( )时的初始化value的采用的是上一次value的值,value在静态区的存储空间并没有因为fun1( )的结束而被释放,即体现了一次存储;
2、 作用域限定:静态修饰的作用域限定功能同时体现在函数与变量上;

a) 对于函数而言,任何用static修饰的函数,其作用域仅为当前源文件,而对外部来说这个函数是不可见的,即只有和其在同一源文件中的函数才能调用这个静态函数;反过来说,如果一个函数仅仅被同一源文件中的其他函数调用,那么这个函数应该声明为静态的,这样做的好处在于:可以一定程度上的解决不同源文件之间函数的命名冲突问题;

b) 对于变量而言,static修饰的全局变量,只在当前源文件中有效,对外部不可见,外部文件不能够引用;

顾名思义,全局变量是指能够在全局引用的变量,相对于局部变量的概念,也叫外部变量;同静态变量一样,全局变量位于静态数据区,全局变量一处定义,多处引用,用关键字“extern”引用“外部”的变量。

全局变量也可以是静态的,在前面有过说明,静态全局变量的意义就是不让“外部”引用,是单个源文件里的全局变量,即是编译阶段的全局变量,而不是连接阶段的全局变量。

通过上面的分析,我们不难得出以下结论:

1、 静态函数与普通函数的区别在于:静态函数不可以被同一源文件以外的函数调用。

2、 静态局部变量与普通局部变量的区别在于:静态局部变量只初始化一次,下一次初始化实际上是依然是上一次的变量;

3、 静态全局变量与普通全局变量的区别在于:静态全局变量的作用域仅限于所在的源文件。




局部变量、全局变量、静态变量
静态变量的类型说明符是static。 静态变量当然是属于静态存储方式,但是属于静态存储方式的量不一定就是静态变量,例如外部变量虽属于静态存储方式,但不一定是静态变量,必须由 static加以定义后才能成为静态外部变量,或称静态全局变量。对于自动变量,它属于动态存储方式。 但是也可以用static定义它为静态自动变量,或称静态局部变量,从而成为静态存储方式。

  由此看来, 一个变量可由static进行再说明,并改变其原有的存储方式。

  1. 静态局部变量

  在局部变量的说明前再加上static说明符就构成静态局部变量。

  例如:

  static int a,b;

  static float array[5]={1,2,3,4,5};

  静态局部变量属于静态存储方式,它具有以下特点:

  (1)静态局部变量在函数内定义,但不象自动变量那样,当调用时就存在,退出函数时就消失。静态局部变量始终存在着,也就是说它的生存期为整个源程序。

  (2)静态局部变量的生存期虽然为整个源程序,但是其作用域仍与自动变量相同,即只能在定义该变量的函数内使用该变量。退出该函数后,尽管该变量还继续存在,但不能使用它。

  (3)允许对构造类静态局部量赋初值。若未赋以初值,则由系统自动赋以0值。

  (4)对基本类型的静态局部变量若在说明时未赋以初值,则系统自动赋予0值。而对自动变量不赋初值,则其值是不定的。 根据静态局部变量的特点, 可以看出它是一种生存期为整个源程序的量。虽然离开定义它的函数后不能使用,但如再次调用定义它的函数时,它又可继续使用,而且保存了前次被调用后留下的值。 因此,当多次调用一个函数且要求在调用之间保留某些变量的值时,可考虑采用静态局部变量。虽然用全局变量也可以达到上述目的,但全局变量有时会造成意外的副作用,因此仍以采用局部静态变量为宜

  2.静态全局变量

  全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。因此static 这个说明符在不同的地方所起的作用是不同的。应予以注意。

  静态变量

  除范围之外,变量还有存活期,在这一期间变量能够保持它们的值。在应用程序的存活期内一直保持模块级变量和公用变量的值。但是,对于 Dim 声明的局部变量以及声明局部变量的过程,仅当过程在执行时这些局部变量才存在。通常,当一个过程执行完毕,它的局部变量的值就已经不存在,而且变量所占据的内存也被释放。当下一次执行该过程时,它的所有局部变量将重新初始化。

  但可将局部变量定义成静态的,从而保留变量的值。在过程内部用 Static 关键字声明一个或多个变量,其用法和 Dim 语句完全一样:

  Static Depth

  例如,下面的函数将存储在静态变量 Accumulate 中的以前的运营总值与一个新值相加,以计算运营总值。

  Function RunningTotal (num)

  Static ApplesSold

  ApplesSold = ApplesSold + num

  RunningTotal = ApplesSold

  End Function

  如果用 Dim 而不用 Static 声明 ApplesSold,则以前的累计值不会通过调用函数保留下来,函数只会简单地返回调用它的那个相同值。

  在模块的声明段声明 ApplesSold,并使它成为模块级变量,由此也会收到同样效果。但是,这种方法一旦改变变量的范围,过程就不再对变量排他性存取。由于其它过程也可以访问和改变变量的值,所以运营总值也许不可靠,代码将更难于维护。

  声明所有的局部变量为静态变量

  为了使过程中所有的局部变量为静态变量,可在过程头的起始处加上 Static 关键字。例如:

  Static Function RunningTotal (num)

  这就使过程中的所有局部变量都变为静态,无论它们是用 Static、Dim 或 Private 声明的还是隐式声明的。可以将 Static 放在任何 Sub 或 Funtion 过程头的前面,包括事件过程和声明为 Private 的过程。

0 0
原创粉丝点击