精华内容
下载资源
问答
  • C语言的变量,按照作用域的范围可分为两种, 即局部变量和全局变量。 、局部变量局部变量也称为内部变量。局部变量是函数内作定义说明的。其作用域仅限于函数内, 离开该函数后再使用这种变量是非法的。...
    
    
    原链接:点击打开链接
    
    

    C语言中所有变量都有自己的作用域,申明变量的类型不同,其作用域也不同。C语言中的变量,按照作用域的范围可分为两种, 即局部变量和全局变量。 一、局部变量

    局部变量也称为内部变量。局部变量是在函数内作定义说明的。其作用域仅限于函数内, 离开该函数后再使用这种变量是非法的。

    例如:

    int f1(int a) /*函数f1*/ {     int b,c

    ……}

    int f2(int x) /*函数f2*/ {     int y,z;

    ……}

    f1内定义了三个变量,a为形参,b,c为一般变量。在 f1的范围内a,b,c有效,或者说a,b,c变量的作用域限于f1内。

    f2内定义了三个变量,x为形参,y,z为一般变量。在 f2的范围内x,y,z有效,或者说x,y,z变量的作用域限于f2内。

    关于局部变量的作用域还要说明以下几点:

             主函数中定义的变量也只能在主函数中使用,不能在其它函数中使用。同时,主函数中也不能使用其它函数中定义的变量。因为主函数也是一个函数,它与其它函数是平行关系。

             形参变量是属于被调函数的局部变量,实参变量是属于主调函数的局部变量。

             允许在不同的函数中使用相同的变量名,它们代表不同的对象,分配不同的单元,互不干扰,也不会发生混淆。虽然允许在不同的函数中使用相同的变量名,但是为了使程序明了易懂,不提倡在不同的函数中使用相同的变量名。

    二、全局变量

    int a,b; /*外部变量*/ void f1() /*函数f1*/ { …… }

    float x,y; /*外部变量*/ int fz() /*函数fz*/ { …… }

    全局变量也称为外部变量,它是在函数外部定义的变量。 它不属于哪一个函数,它属于一个源程序文件。其作用域是整个源程序。在函数中使用全局变量,一般应作全局变量说明。 只有在函数内经过说明的全局变量才能使用。全局变量的说明符为extern 但在一个函数之前定义的全局变量,在该函数内使用可不再加以说明。 例如:   从上例可以看出abx都是在函数外部定义的外部变量,都是全局变量。  对于全局变量还有以下几点说明:

             对于局部变量的定义和说明,可以不加区分。而对于外部变量则不然,外部变量的定义和外部变量的说明并不是一回事。外部变量定义必须在所有的函数之外,且只能定义一次。其一般形式为: [extern] 类型说明符 变量名,变量名… 其中方括号内的extern可以省去不写。    例如: int a,b;    等效于:  extern int a,b;    而外部变量说明出现在要使用该外部变量的各个函数内,在整个程序内,可能出现多次,外部变量说明的一般形式为: extern 类型说明符 变量名,变量名, 外部变量在定义时就已分配了内存单元,外部变量定义可作初始赋值,外部变量说明不能再赋初始值, 只是表明在函数内要使用某外部变量。

             外部变量可加强函数模块之间的数据联系,但是又使函数要依赖这些变量,因而使得函数的独立性降低。从模块化程序设计的观点来看这是不利的, 因此在不必要时尽量不要使用全局变量。

             在同一源文件中,允许全局变量和局部变量同名。在局部变量的作用域内,全局变量不起作用。 int vs(int l,int w) { extern int h; int v; v=l*w*h; return v; } main() { extern int w,h; int l=5; printf("v=%d",vs(l,w)); } int l=3,w=4,h=5;    本例程序中,外部变量在最后定义, 因此在前面函数中对要用的外部变量必须进行说明。外部变量lwvs函数的形参lw同名。外部变量都作了初始赋值,mian函数中也对l作了初始化赋值。执行程序时,在printf语句中调用vs函数,实参l的值应为main中定义的l值,等于5,外部变量lmain内不起作用;实参w的值为外部变量w的值为4,进入vs后这两个值传送给形参lwvs函数中使用的为外部变量,其值为5,因此v的计算结果为100,返回主函数后输出。

    变量的存储类型决定了各种变量的作用域不同。所谓存储类型是指变量占用内存空间的方式,也称为存储方式。变量的存储方式可分为静态存储动态存储两种。    静态存储变量通常是在变量定义时就分定存储单元并一直保持不变, 直至整个程序结束。动态存储变量是在程序执行过程中,使用它时才分配存储单元, 使用完毕立即释放。 典型的例子是函数的形式参数,在函数定义时并不给形参分配存储单元,只是在函数被调用时,才予以分配, 调用函数完毕立即释放。如果一个函数被多次调用,则反复地分配、 释放形参变量的存储单元。从以上分析可知, 静态存储变量是一直存在的, 而动态存储变量则时而存在时而消失。我们又把这种由于变量存储方式不同而产生的特性称变量的生存期。 生存期表示了变量存在的时间。 生存期和作用域是从时间和空间这两个不同的角度来描述变量的特性,这两者既有联系,又有区别。 一个变量究竟属于哪一种存储方式, 并不能仅从其作用域来判断,还应有明确的存储类型说明。

    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 在前面各章的程序中所定义的变量凡未加存储类型说明符的都是自动变量。例如: { 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表明了这种情况。 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+ ap的值为a*a。退出复合语句后的s,p 应为main所定义的s,p,其值在初始化时给定,均为100。从输出结果可以分析出两个s和两个p虽变量名相同, 但却是两个不同的变量。    4. 对构造类型的自动变量如数组等,不可作初始化赋值。    二、外部变量的类型说明符为extern    在前面介绍全局变量时已介绍过外部变量。这里再补充说明外部变量的几个特点:    1. 外部变量和全局变量是对同一类变量的两种不同角度的提法。全局变量是从它的作用域提出的,外部变量从它的存储方式提出的,表示了它的生存期。    2. 当一个源程序由若干个源文件组成时, 在一个源文件中定义的外部变量在其它的源文件中也有效。例如有一个源程序由源文件F1.CF2.C组成: F1.C int a,b; /*外部变量定义*/ char c; /*外部变量定义*/ main() { …… }    F2.C extern int a,b; /*外部变量说明*/ extern char c; /*外部变量说明*/ func (int x,y) { …… }    F1.CF2.C两个文件中都要使用a,b,c三个变量。在F1.C文件中把a,b,c都定义为外部变量。在F2.C文件中用extern把三个变量说明为外部变量,表示这些变量已在其它文件中定义,并把这些变量的类型和变量名,编译系统不再为它们分配内存空间。 对构造类型的外部变量, 如数组等可以在说明时作初始化赋值,若不赋初值,则系统自动定义它们的初值为0 静态变量    静态变量的类型说明符是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值。而对自动变量不赋初值,则其值是不定的。 根据静态局部变量的特点, 可以看出它是一种生存期为整个源程序的量。虽然离开定义它的函数后不能使用,但如再次调用定义它的函数时,它又可继续使用, 而且保存了前次被调用后留下的值。 因此,当多次调用一个函数且要求在调用之间保留某些变量的值时,可考虑采用静态局部变量。虽然用全局变量也可以达到上述目的,但全局变量有时会造成意外的副作用,因此仍以采用局部静态变量为宜。    [5.15] main() { int i; void f(); /*函数说明*/ for(i=1;i<=5;i++) f(); /*函数调用*/ } void f() /*函数定义*/ { auto int j=0; ++j; printf("%d/n",j); }    程序中定义了函数f,其中的变量说明为自动变量并赋予初始值为0。当main中多次调用f时,j均赋初值为0,故每次输出值均为1。现在把j改为静态局部变量,程序如下: main() { int i; void f(); for (i=1;i<=5;i++) f(); } void f() { static int j=0; ++j; printf("%d/n",j); } void f() { static int j=0; ++j; printf("%d/n",j); }    由于j为静态变量,能在每次调用后保留其值并在下一次调用时继续使用,所以输出值成为累加的结果。读者可自行分析其执行过程。    2.静态全局变量    全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序, 当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用, 因此可以避免在其它源文件中引起错误。从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域, 限制了它的使用范围。因此static 这个说明符在不同的地方所起的作用是不同的。应予以注意。    四、寄存器变量    上述各类变量都存放在存储器内, 因此当对一个变量频繁读写时,必须要反复访问内存储器,从而花费大量的存取时间。 为此,C语言提供了另一种变量,即寄存器变量。这种变量存放在CPU的寄存器中,使用时,不需要访问内存,而直接从寄存器中读写, 这样可提高效率。寄存器变量的说明符是register 对于循环次数较多的循环控制变量及循环体内反复使用的变量均可定义为寄存器变量。 ∑200i=1imain() { register i,s=0; for(i=1;i<=200;i++) s=s+i; printf("s=%d/n",s); }    本程序循环200次,is都将频繁使用,因此可定义为寄存器变量。对寄存器变量还要说明以下几点:    1. 只有局部自动变量和形式参数才可以定义为寄存器变量。因为寄存器变量属于动态存储方式。凡需要采用静态存储方式的量不能定义为寄存器变量。    2. Turbo CMS C等微机上使用的C语言中, 实际上是把寄存器变量当成自动变量处理的。因此速度并不能提高。 而在程序中允许使用寄存器变量只是为了与标准C保持一致。3. 即使能真正使用寄存器变量的机器,由于CPU 中寄存器的个数是有限的,因此使用寄存器变量的个数也是有限的。 

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

    原链接:点击打开链接
    静态变量,就是在定义的时候,有static 修饰的变量,形式为
    static TYPE var_name = init_value;
    而动态变量,形式为
    TYPE var_name = init_value;
    即没有static 修饰。其中的=init_value均可省略。
    区分定义在函数外的全局变量,和函数内的局部变量,作用域,生命周期,及无显式初始化时的初始值,均有区别。
    1 动态全局变量:
    作用域为整个项目,即最终编译成可执行文件的所有文件中均可以使用动态全局变量。
    生命周期为从程序运行到程序退出,即贯穿整个运行时间。
    无显式初始化时默认初始化值为0。

    2 静态全局变量
    作用域为当前文件,从定义/声明位置到文件结尾。
    生命周期为从程序运行到程序退出,即贯穿整个运行时间。
    无显式初始化时默认初始化值为0。

    3 动态局部变量
    作用域为当前函数,从定义位置,到其所在的{}的结束位置。
    生命周期为从函数调用到函数退出。
    无显式初始化时默认初始化值为随机值。

    4 静态局部变量
    作用域为当前函数,从定义位置,到其所在的{}的结束位置。
    生命周期为从程序运行到程序退出,即贯穿整个运行时间,当下次函数调用时,静态局部变量不会被再次初始化,而是沿用上次函数退出时的值。
    无显式初始化时默认初始化值为0。
    
    

    #include<stdio.h>
    int fun3(int x)
    {
    	static int a=3;
    	a+=x;
    	return(a);
    }
    main()
    {	
    	int k=2, m=1, n;
    	n=fun3(k);
    	n=fun3(m);
    	printf("%d\n",n);            //6
    }
    #include<stdio.h>
    int fun(int x[],int n)
    {
    	static int sum=0,i;
    	for(i=0;i<n;i++) sum+=x[i];
    	return sum;
    }
    main()
    {
    	int a[]={1,2,3,4,5},b[]={6,7,8,9,},s=0;
    	s=fun(a,5)+fun(b,4);
    	printf("%d\n",s);   //60
    }

    #include<stdio.h>
    int a,b;
    void fun()
    {
    	a=100;
    	b=200;
    }
    
    main()
    {
    	int a=5,b=7;
    	fun();
    	printf("%d,%d\n",a,b);        //5,7
    }

    #include<stdio.h>
    void fun(){
    	static int a=0;
    	a+=2;
    	printf("%d",a);
    }
    
    main(){
    	int cc;
    	for(cc=1;cc<4;cc++) fun();    //246
    	printf("\n");
    }

    以下叙述中正确的是___A___。
    A、局部变量说明为static 存储类,其生存期将得到延长
    B、全局变量说明为static 存储类,其作用域将被扩大
    C、任何存储类的变量在未赋初值时,其值都是不确定的

    D、形参可以使用的存储类说明符与局部变量完全相同



    展开全文
  • C/C++语言的变量分为全局变量和局部...虽然常见的局部变量都是定义在函数体内的,也完全可以人为的增加一对大括号来限定变量作用域。如下所示:void f() { float x = 0; { int a; } }别小看这作用域问题,这对

    C/C++语言中的变量分为全局变量和局部变量。这种划分方式的依据是变量的可见范围或者叫做作用域

    1 局部变量

    局部变量指的是定义在{}中的变量,其作用域也在这个范围内。虽然常见的局部变量都是定义在函数体内的,也完全可以人为的增加一对大括号来限定变量作用域。

    如下所示:

    void f()
    {
        float x = 0;
        {
            int a;
        }
    }

    别小看这个作用域问题,这对于C++的影响远比纯C要大。C语言中局部变量离开作用域时,编译器会插入一个POP 指令来清理变量占用的栈空间。而在C++中,除了POP指令,还要调用析构函数。

    class MyClass
    {
        MyClass(){}
        ~MyClass(){}
    };
    
    void f()
    {
        {
            MyClass a;
        } // 此处会C++编译器被插入调用~MyClass()的代码
        do_someting();
    }

    C++编译器在对象a的作用域结束之前,自动插入调用~MyClass()的汇编代码。

    局部变量作用域是由编译器强制实施的,这样一旦出现作用域外访问,编译时就会报错,从而帮助程序员排除错误。

    2 全局变量

    全局变量的作用域是整个工程,也就是在所有参与链接的文件中都是可见的。这就会导致一个问题-名称冲突。例如下面工程中有3个源文件main.c, 1.c, 2.c。

    main.c

    #include <stdio.h>
    int main(int argc, char** argv)
    {
        return 0;
    }
    

    1.c

    int a = 1;

    2.c

    int a = 2;

    编译每个文件都是可以通过的,但是链接时会报错,因为1.c和2.c使用了同一个名称的全局变量。为此,C语言的全局变量被给予了极坏的形象。甚至不使用全局变量的教条在很大范围内盛行。

    然而全局变量在很多时候还是必须的,至少是使用它会让问题变得方便。例如当一个变量是很多函数的参数时。

    void f1(int a);
    void f2(int a);
    void f3(int a);

    这样每次调用函数都需要传递这个变量a,当这样的参数个数增多时,会让人变得发狂。如

    void f1(int a, int b, int c, int d, int e);
    void f2(int a, int b, int c, float g);
    void f3(int a, int b, int c, int d);

    这种情况在需要保存状态的程序中很常见,如GDI库,OpenGL库等。此时采用全局变量来维护状态数据是非常好的选择。C++看到了这种需要,所以索性把这些状态数据和算法函数绑定到了一起,形成了的概念,从而简化了代码设计。

    3 文件级变量

    很多时候,其实程序员需要变量的可见范围既不是整个工程,也不是函数内部,而是在当前文件中可见。C语言为此提供了静态全局变量。static global variable。这个名称完全没有能够反映出变量作用域的范围,是一个非常糟糕的名字。而且起关键字static更是让人摸不着头脑。

    static int a = 100;

    C语言的设计者或许是为了节省关键字的使用,很多关键字用在不同的地方都有完全不同的含义。这种设计应该是仁者见仁的事情,我个人觉得如果此处使用其他的关键字如internal来标识,会更容易让人理解。

    internal int a = 100;

    好像在C#中确实存在类似的关键字来表示作用域。

    言归正传,static 修饰的全局变量只在定义它的文件内部有效,其他文件内无法引用它。上面的例子改为:
    main.c

    #include <stdio.h>
    int main(int argc, char** argv)
    {
        return 0;
    }
    

    1.c

    static int a = 1;

    2.c

    int a = 2;

    此时,项目会链接成功。因为全局范围内只有一个名为a值为2的全局变量,值为1的那个a只在1.c内有效。

    4 C和C++编译器对const常量的一点不同

    C++编译器对const常量会自动增加static关键字,使其作用域为文件级别。而C语言编译器则不会。如下代码:

    main.c

    #include <stdio.h>
    int main(int argc, char** argv)
    {
        return 0;
    }
    

    1.c

    const int a = 1;

    2.c

    int a = 2;

    使用C++编译器可以顺利编译链接成功,但是使用C编译器则在连接时报错。为了代码的可移植性,最好还是手动把 static const都写上。

    main.c

    #include <stdio.h>
    int main(int argc, char** argv)
    {
        return 0;
    }
    

    1.c

    static const int a = 1;

    2.c

    int a = 2;

    上述代码则在C和C++编译器下均可编译链接成功。

    展开全文
  • 外部变量是函数的外部定义全局变量,它的作用域是从变量的定义处开始一直到本程序的结尾。但有以下希望能扩展外部变量的作用域的情况:

    外部变量是在函数的外部定义的全局变量,它的作用域是从变量的定义处开始一直到本程序的结尾。但有以下希望能扩展外部变量的作用域的情况:

    1、在一个文件内扩展外部变量的作用域

    外部变量的作用域为定义处到文件结束,在定义之前的函数都不能引用该外部变量。但是如果需要定义点之前的函数也能引用该外部变量,则应该在引用之前使用关键字extern对该变量作“外部变量声明”,表示把该外部变量的作用域扩展到此位置,那么就能在该外部变量定义处之前合法使用该外部变量了。
    例子:

    #include<stdio.h>
    
    //调用函数,求三个整数中的大者
    //用extern声明外部变量,扩展外部变量在程序文件中的作用域
    
    int max();
    
    int main()
    {
    	extern int a, b, c;      //把外部变量a,b,c的作用域扩展到从此处开始
    	printf("input three integer numbers:");
    	scanf_s("%d %d %d", &a, &b, &c);
    	printf("max is %d\n", max());
    
    	system("pause");
    
    }
    
    int a, b, c;               //定义外部变量a,b,c
    
    int max()
    {
    	int m;
    	m = a > b ? a : b;
    	if (c > m)
    	{
    		m = c;
    	}
    	return m;
    }
    

    运行结果:
    在这里插入图片描述

    解析:

    • 由于外部变量a,b,c是定义在main()函数后面的,因此本来在main()函数中应该是不能引用外部变量a,b,c的。但是由于在main()函数中用extern关键字对a,b,c进行了“外部变量声明”,把a,b,c的作用域扩展到该位置。这样就可以在main()函数中合法地使用全局变量a,b,c了;

    • 由于a,b,c是外部变量,因此在调用max()函数时不用传递参数,可以直接使用a,b,c

    • 使用extern声明外部变量时,类型名可以省略。
      例如:

    extern int a,b,c  等同于 extern a,b,c
    

    因为这不是定义变量,可以不指定类型,写出外部变量名即可。


    **

    2、将外部变量的作用域扩展到其它文件

    **

    第一种情况是在同一个源文件中使用外部变量的方法,如果有多个源文件,想在A文件中引用B文件中的已定义外部变量,该如何做?

    • 假设一个程序包含两个文件,两个文件都需要用到同一个外部变量Num,若在两个文件中各自定义一个外部变量Num,将会在进行程序的连接时出现“重复定义”的错误。
    • 因此,正确的做法是:在任一个文件中定义外部变量Num,然后在另一个文件中用关键字extern进行“外部变量声明”,即“extern Num”。
    • 在编译和链接时,系统就会知道Num有外部链接,可以从别处找到已定义的外部变量Num,并将另一个文件中定义的外部变量Num的作用域扩展到本文件,那么就可以在本文件中合法的使用变量Num了。
      例子:
      分别编写两个源文件文件file1和file2,在file1中定义外部变量A,在file2中用extern来声明外部变量,把A的作用域扩展到file2中

    file1:

    //file1
    #include<stdio.h>
    
    //给定b的值,输入a和m,求a*b和a**m(a的m次方)的值
    
    int A;     //定义外部变量
    int power(int);
    
    int main()
    {
    	int b = 3, c, d, m;
    	printf("input a and its power m:");
    	scanf_s("%d %d", &A, &m);
    	c = A * b;
    	printf("%d*%d=%d\n", A, b, c);
    	d = power(m);
    	printf("%d ** %d=%d\n", A, m, d);
    	system("pause");
    }
    

    file2:

    //file2
    extern A;             
    //把在file1文件中已定义的外部变量的作用域扩展到本文件
    int power(int n)
    {
    	int i, y = 1;
    	for ( i = 1; i <= n; i++)
    	{
    		y *= A;
    	}
    
    	return y;
    }
    

    运行结果:
    在这里插入图片描述

    解析:

    • 假设某一程序有5个源文件,那么只需要在其中一个源文件中定义外部变量A,然后在其余四个文件中使用关键字extern声明外部变量即可。各文件经过编译后会连接成一个可执行的目标文件。
    • 用这种方法扩展全局变量的作用域应十分慎重,因为在执行一个文件中的操作时可能会改变该全局变量的值,这样就会影响到另一个文件中全局变量的值,从而影响该文件中函数的执行结果。

    3、将外部变量的作用域限制在本文件中

    若希望外部变量仅限于被本文件使用,而不被其它文件使用,那么可以在定义外部变量时加上一个static,例如:

    static int A;
    int main()
    {
    	......
    }
    

    这样在其它文件中就算使用“extern A”,也不能使用本文件的外部变量A。

    这种加上static声明,只能用于本文件的外部变量成为“静态外部变量”。

    用static声明一个变量的作用:
    (1)对局部变量用static声明,把它分配在静态存储区,该变量在整个程序执行期间所在的存储单元都不会释放。
    (2)对全局变量用static声明,则该变量的作用域只限于本文件模块(即被声明的文件中)

    展开全文
  • 能不能头文件中定义全局变量

    万次阅读 多人点赞 2018-01-29 22:51:55
    首先,这是一篇科普文,所以比较杂,我尽量写清楚一些。 1、ANSIC标准是什么?GNU又是什么?ld是什么? ANSIC是C语言的标准规范,是国际标准化组织...因此可以将现实C语言实现看作是ANSIC的一个超集。比较有代表

    首先,这是一篇科普文,所以 比较杂,我尽量写清楚一些。

     

    1、ANSI C标准是什么?GNU又是什么?ld是什么?

     

    ANSI C是C语言的标准规范,是国际标准化组织制定的国际标准。

     

    虽然 ANSI C规范了C语言的实现,但是在实际情况中,各家C语言提供商都会根据平台的不同情况对ANSI C进行一定的扩展。因此可以将现实中C语言实现看作是ANSI C的一个超集。比较有代表性的例子是linux的gcc编译器。由于该编译器对ANSI C进行了非常多的扩展,linux内核源码基本上只能在gcc上面 进行编译,希望通过其他的编译器来编译linux内核几乎是不可能的。

     

    GNU计划,又称革奴计划。它的目标是创建一套完全自由的操作系统。1990年,GNU计划已经开发出的软件包括了一个功能强大的文字编辑器Emacs  。GCC(GNU Compiler Collection,GNU编译器集合),是一套由 GNU 开发的编程语言编译器。

     

    GNU工具链包括了构建linux开发环境所需的编译、链接、调试、软件工程等工具。GCC(编译器)、Gdb(调试器)、make(软件等工程工具)。GCC下包括gcc,g++工具。GNU binutils是一组二进制工具程序集,是辅助GCC的主要软件,包括我们熟悉的as(GNU汇编器),ar(建立、修改、提取归档文件,归档文件是包含多个文件内容的一个大文件)、ld(连接器,把目标文件和归档文件结合在一起),我们在写程序的时候,有时候报错:[Error] ld returned 1 exit status,这就是程序在链接的时候出错了。

     

     

    2、C语言可以在不同的源文件中定义相同名字的全局变量吗?

     

    不使用static的时候,两个不同的源文件都可以正常编译,但会出现链接错误,原因是有两个地方存在相同的变量,导致编译器无法识别应该使用哪一个。

     

    关于全局变量的几点说明:

    ①默认情况下,C语言中的全局变量和函数的作用域仅限于定义和声明这个函数或变量的内部,如果需要从这个C文件之外访问这些函数或者全局变量就需要使用 extern关键字进行声明,这是因为C编译器是以C文件为单位进行编译的,如果这个C文件中引用了其他文件中定义的函数或者变量,编译器将无法找到这个函数或者变量的定义,从而给出该函数或者变量未定义的错误信息。

     

    ②static关键字用于全局变量的声明时,作用类似于函数的情况,这个全局变量的作用域将局限在声明该变量的c文件内部,这个c文件之外的代码将无法访问这个变量。编译的时候将会出现类似undeference to "xxx"的报错,它是找不到xxx的,因为使用static相当于进行了文件隔离。

     

     

    3、那么再引申另一个问题,能不能在头文件中定义全局变量?

     

    因为变量只能被定义一次,包含了头文件的源文件,都将会定义同样的全局变量,造成冲突,所以,头文件中不能定义全局变量。还有网友从节省内存的角度来分析,还得到了很多赞,我觉得解释的不对啊!详见c语言 中 为什么不将全局变量的定义放在头文件中

     

     

    4、本博客的导火索,

     

    就是因为在一个大的工程中,需要增加一个全局变量,一开始我是加在了某一个头文件中,然后报重复定义的错误,很显然,就是因为第2点中说的,由于这个头文件被多个源文件include,虽然在编译阶段可能能通过,但是在链接的时候就会出现重复定义的错误。

     

    解决办法:

    ①处于尽可能的改动较少的文件的文件的原则,自己写一个头问价,文件内容就一条:全局变量的定义。这样的话,在需要使用的位置通过include这个头文件就可以了。但是,如果有多个源文件需要使用使用这个变量的话,这种情况也会发生重复定义的错误,因为include的过程就是复制的过程,那么很显然了,这个头文件被拷贝到了多个源文件中,链接时肯定会出现重复定义的错误啊。

     

    而且,假设只有一个源文件需要这个全局变量,那么直接在这个源文件中定义全局变量就好了啊!还定义什么鬼头文件哦!

     

    ②假设工程中的多个源文件需要这个全局变量,那么你就任找一个源文件,把这个全局变量定义到这个源文件中,然后新建一个头文件,在里面进行extern 这个变量的声明,最后在需要使用这个全局变量的源文件中include你新建的头文件就OK了。

     

     

    参考:

    [1] 嵌入式系统高级C语言编程,凌明编著,第一章概述

    [2] C语言可以在不同的源文件中定义相同名字的全局变量吗

    展开全文
  • 全局变量和静态变量的存储方式是一样的,只是... 值得注意的是:如果头文件定义全局变量预编译期间#include的头文件会被拷贝进源文件,编译器是不知道头文件的。虽然全局变量是全局作用域,但需要extern关...
  • 什么是变量变量常量都是表征数据的一种形式;...变量和常量必须用标识符(或者可以理解成一个名字)来表示后才能使用。 赋值表达式语句把值赋给变量,或者更一般地说,把值赋给存储空间。 +++++++++++...
  • c/c++全局变量在个源文件中的使用

    千次阅读 2016-04-11 15:47:06
    c/c++ 全局变量 多文件使用
  • 这两者的区别虽在于非静态全局变量作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。而静态全局变量则限制了其作用域,即只在定义该变量的源文件
  • 1、ANSIC标准是什么?GNU又是什么?ld是什么? ...ANSIC是C语言的标准规范,是国际标准化组织制定的国际标准...虽然ANSIC规范了C语言的实现,但是实际情况,各家C语言提供商都会根据平台的不同情况对ANSIC进行...
  • 程序的开头定义的是全局变量函数内部定义的是局部变量。 这里涉及2概念,作用域与生命周期。 作用域指的是描述变量哪段代码有效;生命周期指的是变量什么时候被创建,什么时候被释放。 特别注意的...
  • 多个文件如何共用一个全局变量

    千次阅读 2020-02-19 12:17:07
    多个文件如何共用一个全局变量 例子: 头文件:state.h源文件:...需要定义一个全局变量供这些源文件中使用:方法如下 1、 state.h声明全局变量: extern inta; 2、state.cpp中定义全局变量:int a =10;...
  • 一个x,零的作用域为定义它的语句块作用域(红色格格),里面的橙色格格。 2、作用域较小的局部变量隐藏作用域较大的局部变量 例如:上图里的运算结果: 此时 int x = 1, y = 1;作用域较小会隐藏 x = 0, y...
  • 全局变量只需在一个源文件中定义,就可以作用于所有的源文件。当然,其他不包含全局变量定义源文件需要用extern关键字再次声明这个全局变量。 2>静态局部变量具有局部作用域,它只被初始化一次
  • 不管是全局还是局部声明的static变量都存放于程序的全局变量区域,全局变量也是存放于程序的全局变量区域,所以它们的生命周期是从程序开始到程序结束。 它们的作用域决定于它被存放和定义的位置。
  • 本博客仅记录自己代码...例如程序包含两个源文件两个源文件中都要用到同一个外部变量a,做法任意一个源文件中定义外部变量a,而另一文件中用extern对a作“外部变量申明”,即“extern a”。 文件file1.c
  • golang if 声明变量作用域

    千次阅读 2019-06-22 15:03:27
    变量作用域变量定义if 和 for 声明变量作用域if 和 for 这些控制结构,而这些结构声明的变量的作用域只相应的代码块内。 一个变量(常量、类型或函数)程序中都有一定的作用范围,称之作用域。如果一个...
  • C++局部变量可否与全局变量重名

    千次阅读 2019-01-19 14:11:31
    局部变量(通常函数中定义)的作用域是从声明的那一点开始,直到这个声明所在的块结束为止(一个块就是由{}围起来的一段代码)。全局变量所有函数、类、命名空间之外定义)的作用域从声明的那一点开始,直到这...
  • 等效于每个引用该头文件的源文件中定义一个变量名var, 类型TYPE的静态全局变量。每个文件的var变量均归属于本源文件,各文件的互不相同。 作用域为引用头文件的源文件范围内。 2 头文件中定义变量,...
  • 全局变量及其作用域-外部变量:extern

    千次阅读 2014-04-14 10:58:48
    全局变量是函数外部定义的变量, 它不属于哪一个函数,它属于一个源程序文件.其作用域是从变量定义的位置开始,到整个源文件结束. 全局变量可以被作用域内的...如果在定义全局变量的时候未进行初始化,则自动地被初始化为
  • C++全局变量声明和定义

    万次阅读 2018-12-07 22:00:23
    全局变量整个源文件作用域都是有效的,只需要在一个源文件中定义全局变量其他不包含全局变量定义的源文件中用extern关键字再次声明这个全局变量即可。 也可以在一个源文件中定义这个全局变量,头文件中用...
  • 例子: 头文件:state.h 源文件:state.cpp ...需要定义一个全局变量供这些源文件中使用:方法如下 1、 state.h声明全局变量: extern int a; 2、state.cpp中定义全局变量:int a = 10; 这样其它源文件就可以
  • 区别:使用static存储类别的全局变量只能定义的源程序文件使用,而使用extern存储类别的全局变量不仅可以定义的源程序文件使用,还可以被其他源文件中的函数引用。 局部变量 相对于全局变量而言的,即...
  • 头文件只是用来声明的,不参与编译,#include “1.h” 只是把1.h里的代码给复制到这个源文件里来,建议还是好好...1)不管变量还是函数先声明 或者直接定义才能使用,声明能声明n次,同一个作用域里面 定义只能定义...
  • C语言变量按其作用域分,可分为局部变量和全局变量,具体的解释: 局部变量(内部变量):在定义它的函数内有效,但是函数返回后失效; 全局变量(外部变量):所有源文件内均有效。同源文件的函数使用...
  • 全局变量作用域为定义处到所在源文件结束,但是可以使用extern关键字来扩充其作用域(可以其他源文件使用)。当使用static关键字修饰时,将其作用域限定其所在源文件,这样和其他源文件中同名变量不会冲突。...
  • 1、普通全局变量:假设我们需要多个不同的编译单元(比如两个.cc文件)使用全局变量进行传值,如我们有如下三个源码文件:main.cc:运行入口,有一个main函数,其中会打印出全局变量var的值;[cpp] view plain...
  • 例子: 头文件:state.h 源文件:state.cpp 其它源文件:t1.cpp t2.cpp t3.cpp, 这些源文件都包含头文件state.h。...需要定义一个全局变量供这些源文件中使用:方法如下 1、 state.h声明全局变量: extern ...
  • 全局变量的声明、定义及用法

    万次阅读 多人点赞 2019-01-20 21:38:46
    全局变量(extern)4.1 如果直接将声明和定义都放在头文件会如何?5. 静态全局变量(static)6. 全局常量(const) 转载自https://blog.csdn.net/candyliuxj/article/details/7853938 转载自htt...
  • 对于有些编译器而言,一个函数内可以定义多个同名的局部变量,比如两个循环体内都定义一个同名的局部变量,而那个局部变量的作用域那个循环体内。 2、如何引用一个已经定义过的全局变量...
  • 全局变量只需在一个源文件中定义,就可以作用于所有的源文件。当然,其他不包含全局变量定义源文件需要用extern 关键字再次声明这个全局变量。 2、静态局部变量具有局部作用域,它只被初始化一次,自从第一次被...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 31,420
精华内容 12,568
关键字:

在一个源文件中定义的全局变量的作用域为