您的位置:首页 > 编程语言 > C语言/C++

c++ 变量存储性质与标识符作用域

2017-03-12 16:03 197 查看

                                                    

                                                                变量存储特性与标识作用域

     首先:一个被说明的变量,除名字,类型和值的基本特性外,还有其他特性,包括存储,作用域,可见性和连续等特性。
     标识符存储特性确定了标识符在内存中的生存时间和连续特性。
     c++的一个程序称为一个项目。一个项目可以由多个文件组成。标识符的连续特性决定标识符能否被工程中其他文件引用。

1.存储特性

    c++中有两种存储特性,分别为:自动存储,静态存储

    1). 自动存储(只有变量才具有的存储特性)
          自动存储用关键字 auto 和 register 说明。这种变量在进入说明的时生成,在结束块时删除。

          函数的参数和局部变量都是自动存储的。  

           auto:为变量默认的存储类型,因此很少用

           register:将变量存放在寄存器中(原因可以自己百度查找)

     2).静态存储

          关键字 extern 和 static 说明静态存储变量和函数标识符。

          如果这两个关键字用于说明变量,程序在开始执行时就分配和初始化存储空间;如果用于说明函数时,表示从程序执行开始就存在这个函数名。

          尽管标识符被说明为静态时,程序一开始就存在,但不等于他们在整个程序中可用。

          extern:全局说明的标识符默认为extern。

          static:static说明的局部变量只能在定义该变量的函数体中使用。与自动变量不同的是,static在第一次使用时进行初始化(默认初始值为0)。函数退出时,系统保持其存储空间和数值。下次调用这个函数时,static变量还是上次退出时函数的值。

#include <iostream>

#include <stdlib.h>

using namespace std;

int func()

{
int a = 0;              //自动变量a,再次调用时重新分配存储空间
static int b = 1;      //静态变量b,再次调用的时候保留原值
++a;
++b;
cout << "auto a=" << a << endl;
cout << "static b=" << b << endl;
return a + b;

}

int main(void)

{
cout << func() << endl;
cout << func() << endl;
system("pause");
return 0;

}

程序运行结果:
auto a=1

static b=2

3

auto a=1

static b=3      //可以看出,再次使用b的值时b的初始值为上次调用后的结果

4

请按任意键继续. . .

         

 2.标识符的作用域与可见性

    程序中常用的标识符有变量、常量、函数、类型等命名符。
    c++的标识符有5种作用域:函数原型、块、函数、类和文件作用域。
     1).函数原型作用域
             只有函数原型形式参数表中使用的标识符才具有函数原型的作用域。
     2).块作用域
         块是指在函数定义中由一对花括号相括的一段程序单元。一个程序块内允许嵌套嵌套另外一个块。在块中说明的标识符具有块作用域,其作用域从说明点开始,直到结束块的右括号处为止。

#include <iostream>

#include <stdlib.h>

using namespace std;

int main(void)

{
double a;
cin >> a;
while (a > 0)
{
double sum = 0;   
sum += a;
cin >> a;
}
//cout << sum << endl;     错误,未定义变量
system("pause");
return 0;

注:如果嵌套的内层块与外层块有同名的变量,则内层块的内部变量将覆盖外层的同名变量。作用域不同的变量,系统分配不同的存储空间,它们的生存期也不同。
       3).函数作用域
         语句标号(后面带冒号的标识符)是唯一具有函数作用域的标识符。语句标号一般用于switch结构中的case标号,以及goto语句转向入口的语句标号。标号可以在函数体的任意位置,但不能在函数体外引用。
         实际上函数体是一个特殊的语句块。
      4).文件作用域
           任何在函数之外说明的标识符都具有文件作用域(注意,这里是函数外)。这种标识符从定义到文件尾部任何一个函数都可见。
       5).全局变量和局部变量
            具有文件作用域的变量称为全局变量,具有块作用域的变量称为局部变量。全局变量说明时默认初始值为0.当局部变量与全局变量同名时,在块内,全局变量被屏蔽。要在块中访问全局变量,可以用作用域运算符“::”

//在函数体内访问全局变量
#include <iostream>

#include <stdlib.h>

using namespace std;

int x;

int main(void)

{
int x = 256;
cout << "global variable x=" << ::x << endl;   //用作用
b07b
域符指定访问
cout << "local variable x=" << x << endl;
system("pause");
return 0;

}

运行结果:
global variable x=0

local variable x=256

请按任意键继续. . .

注:若是外层块和内层块有同名变量时,在内层块中不可以通过作用域符号进行访问外层变量。这是块作用域变量与全局变量不同的地方。

由上述可知,内层块可以说明与外层块同名的变量,函数可以通过非局部变量返回运算结果。但将变量说明为全局变量可能发生意料不到的副作用。有时,不需要访问该变量的函数可能会意外修改了它,产生难以查找的错误。
除非有特殊的要求,否则程序中不应该使用全局变量。当函数的数据传输只使用参数而不需要全局变量时,我们称这个函数低耦合度的。低耦合度的程序模块便于调试,便于重用。

注:如有不全或者错误希望各位大神补充或指出,希望对大家有帮助!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++