学习C++的全局变量

152 阅读3分钟

一个内存位置需要被识别,它由一个名称来识别,称为变量。一个程序的长度,从上到下,有不同的部分,做不同的事情。有些部分是相关的,但在长度上是不连续的。不连续的部分的长度间隔有其他部分,这些部分与其他部分相关。

一个作用域是一组相关的部分,在这里可以使用或看到一个变量。作用域有名称。全局变量是一个可以在程序的每个作用域中看到的变量。一个全局变量可以有不同的类型。这篇文章解释了如何在常见的作用域中看到一个全局变量。

文章内容

相关部分

考虑一下下面的程序。

  #include <iostream>
    using namespace std;

    int it = 5;
    float ft = 2.7;

    int fn1 (int integ = it)
    {
        /* statements */
        return integ;
    }

    float fn2 (float flt = ft)
    {
        /* statements */
        return flt;
    }
   
    int main()
    {
        cout << fn1() << endl;
        cout << fn2() << endl;

        return 0;
    }

输出结果是:

  5
    2.7

变量 "it "和ft是不同的类型。首先考虑变量 "it":"it "是在其声明行中看到的。一些行被跳过。然后在fn1()的签名中可以看到它。在fn1()的整个主体中也可以看到它。一些行和一部分被跳过。然后可以在main()函数的整个主体中看到它。实际上,在main()函数的第一条语句中,通过fn1()函数的调用,可以间接地看到它。刚才已经说明了变量 "it "的部分内容。

现在考虑一下变量ft:ft在其声明行中被看到。一些行和一个部分(fn1定义)被跳过。一个空行被跳过。然后在fn2()的签名中看到了它。在fn2()的整个主体中可以看到它。然后可以在main()函数的整个主体中看到它。实际上,在main()函数的第二条语句中,通过fn2()函数的调用,可以间接地看到它。刚才已经说明了变量'ft'的部分内容。

全局范围和全局变量

当程序员刚开始输入一个文件时,这就是全局范围。考虑一下下面的程序。

 #include <iostream>
    using namespace std;

    char var = ‘E’;

    int main()
    {
        cout <<var<<'\n';
        cout <<::var<<'\n';

        return 0;
    }

输出结果是:

E  
E

在这个程序中,var的部分或范围从var的声明点开始,一直向下延伸到翻译单元(文件)的结束。

main()函数的主体本身就是一个不同的作用域;全局作用域嵌套了main()函数作用域。

变量var是一个全局范围的变量,因为它可以在文件中的任何地方看到,从它被声明的地方开始。在main()函数作用域中可以看到它。在前面的程序中,"it "和ft是全局范围变量。每个变量都可以在其声明行、函数作用域和main()函数作用域中看到。

为了从不同的作用域访问一个全局变量(全局作用域的变量),直接使用变量名或在其前面加上作用域解析操作符::,如上面的程序所示。

解释代码:C++中的所有程序都应该至少以本程序开始的前两行为起点。这两行是

 #include <iostream>
 using namespace std;

这里的第一行不是一个语句;它是一个指令,一个包含指令。它包括了输入/输出流库,它负责向终端发送输出和接收键盘的输入。终端和键盘一起被称为控制台。这个库被称为iostream库(即输入/输出流库)。

程序中的第二行不是指令,它是一个语句,以分号结束。它说在它下面使用的任何名称都来自标准名称空间,除非另有说明。读者可能会感兴趣,知道命名空间有一个范围;然而,这将不会在本文中讨论。

前两行下面的语句是一个char变量的完整声明。在main()函数中,前两行以稍微不同的方式向终端打印同一个变量的值。

区块范围和全局变量

复合语句的例子是if、while、do、for或switch语句。这些复合语句中的每一个都可以有一个块。块范围变量是指在块中定义的变量。它的范围从它的声明点开始,到它的块的结束点结束。一个全局变量通常是在这个块之外和之上定义的。一个全局变量可以在这个块外、这个块的头行和块内看到。下面的程序用一个if块来说明这一点。

 #include <iostream>
    using namespace std;

    int i = 5;
   
    int main()
    {
        cout << "First i is: " << i << endl;

        if (i == 5) {
            cout << "Second i is same: " << i  << endl;
        }

        return 0;
    }

输出的结果是:

  First i is: 5
  Second i is same: 5

if-block是一个嵌套到main()函数作用域的块,而main()函数作用域是一个嵌套到全局作用域的块。这个程序表明,全局变量可以在嵌套块中看到。

嵌套块中的重写

一个全局变量可以在嵌套块中被覆盖。也就是说,在嵌套块中,全局变量可以被同名的变量所取代。在下面的程序中,i在嵌套块中被另一个实体--float取代。而这就是规则。嵌套作用域中与作用域外的变量同名的变量会覆盖该外层变量。所以,对于嵌套的作用域来说,在嵌套的作用域外声明的同名变量不能在嵌套的作用域内看到;因为嵌套的作用域内的变量已经在嵌套的作用域内占据了它的位置。嵌套的范围内的那个变量从它的声明点到它的块的末尾都可以看到。嵌套的范围内的那个不需要与嵌套的范围外的那个有任何关系。这个程序是

 #include <iostream>
    using namespace std;

    int i = 5;
   
    int main()
    {
        cout << "First i is: " << i << endl;

        if (i == 5) {
            float i = 7.0;
            cout << "Second i is different: " << i  << endl;
        }

        return 0;
    }

输出的结果是:

  First i is: 5
  Second i is different: 7

重载变量的名称是一样的,而且仍然可以是相同的类型。

普通函数范围和全局变量

考虑一下下面的程序。

 #include <iostream>
    using namespace std;

    int fn (int integ);

    int i = 5;

    int fn (int integ = i)
    {
        /* statements */
        return integ;
    }
   
    int main()
    {
        cout << fn() << endl;

        return 0;
    }

函数fn()的声明区域由其原型的 "int fn (int integ); "一行、全局范围内的定义部分和主函数体中的调用语句组成,输出为5。所有这些行和部分构成了函数fn()的范围。fn()的函数签名是函数范围的一部分(也是主体的一部分)。现在,全局变量i已经在fn函数的所有行或部分中出现。

考虑一下下面的程序,有类和实例化的对象。

 #include <iostream>
    using namespace std;

    int i = 5;

    class Calc {
        private:
        int pM = i;
        public:
        void mfn(int inte = i)
            {
                cout << inte << endl;
            }
    };

    class DCla: public Calc
        {
            public:
            int dM = i;
        };
        
    int main()
    {
        Calc obj;
        obj.mfn();
        DCla dObj;
        cout << dObj.dM << endl;

        return 0;
    }

输出结果是:

5  
5

该程序有一个基类,Calc,和它的派生类,Dcla。基类对派生类是公开的:这意味着派生类可以看到基类的受保护成员。所以Calc类的部分是它的块和派生类Dcla的块。也就是说,Calc这个类的范围有两个部分。现在,全局变量i可以在这两个部分看到。

结论

一个内存位置需要被识别,它由一个名称来识别,称为变量。一个程序的长度,从上到下,有不同的部分,做不同的事情。有些部分是相关的,但在长度上是不连续的。不连续的部分的长度间隔有其他部分,这些部分与其他部分相关。

一个作用域是一组相关的部分,在这里可以使用或看到一个变量。作用域有名称。全局变量是一个可以在程序的每个作用域中看到的变量。一个全局变量可以是任何类型的。