变量存储特性与标识作用域
首先:一个被说明的变量,除名字,类型和值的基本特性外,还有其他特性,包括存储,作用域,可见性和连续等特性。
标识符存储特性确定了标识符在内存中的生存时间和连续特性。
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; //用作用域符指定访问 cout << "local variable x=" << x << endl; system("pause"); return 0; }
运行结果:
global variable x=0 local variable x=256 请按任意键继续. . .
注:若是外层块和内层块有同名变量时,在内层块中不可以通过作用域符号进行访问外层变量。这是块作用域变量与全局变量不同的地方。
由上述可知,内层块可以说明与外层块同名的变量,函数可以通过非局部变量返回运算结果。但将变量说明为全局变量可能发生意料不到的副作用。有时,不需要访问该变量的函数可能会意外修改了它,产生难以查找的错误。
除非有特殊的要求,否则程序中不应该使用全局变量。当函数的数据传输只使用参数而不需要全局变量时,我们称这个函数低耦合度的。低耦合度的程序模块便于调试,便于重用。
注:如有不全或者错误希望各位大神补充或指出,希望对大家有帮助!
转载请注明原文地址: https://ju.6miu.com/read-34642.html