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

    作者:课课家教育更新于: 2016-01-20 18:36:42

    大神带你学编程,欢迎选课

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

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

      main.c

      #include

      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

      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

      int main(int argc, char** argv)

      {

      return 0;

      }

      1

      1.c

      const int a = 1;

      1

      2.c

      int a = 2;

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

      main.c

      #include

      int main(int argc, char** argv)

      {

      return 0;

      }

      1.c

      static const int a = 1;

      2.c

      int a = 2;

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

    C/C++语言中变量作用域:局部变量,全局变量,文件级变量_Java技术_C语言_课课家

c++ 更多推荐

课课家教育

未登录