• C/C++语言中变量作用域:局部变量,全局变量,文件级变量


    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 全局变量

    全局变量的作用域是整个project。也就是在全部參与链接的文件里都是可见的。这就会导致一个问题-名称冲突。

    比如以下project中有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 文件级变量

    非常多时候,事实上程序猿须要变量的可见范围既不是整个project。也不是函数内部,而是在当前文件里可见。C语言为此提供了静态全局变量

    static global variable。这个名称全然没有能够反映出变量作用域的范围。是一个非常糟糕的名字。

    并且起关键字static更是让人摸不着头脑。

    static int a = 100;

    C语言的设计者也许是为了节省关键字的使用,非常多关键字用在不同的地方都有全然不同的含义。这样的设计应该是仁者见仁的事情,我个人认为假设此处使用其它的关键字如internal来标识,会更easy让人理解。

    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++编译器下均可编译链接成功。

  • 相关阅读:
    Datasnap http用户验证
    Delphi 接口机制真相
    tfmxobject的序列化
    delphi md5算法
    delphi xe 窗体子控件实现窗体拖动
    Delphi笔记-自定义组件
    DELPHI RES资源文件使用方法
    Delphi中WebBrowser的使用技巧汇总
    Delphi XE调用第三方库Jni详细过程
    使用VLC进行屏幕广播
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/8858241.html
Copyright © 2020-2023  润新知