1.作用域
作用域是一个标识符在程序正文中的有效的区域
作用域包含:函数原型作用域,局部作用域,类作用域,文件作用域,命名空间作用域,和限定作用域的enum枚举类
- 函数原型作用域(c++中最小的作用域)
定义:在函数原型声明时参数形式的作用范围就是函数原型作用域
举例:double area(double radious);这是一个函数的声明
即标识符radious的作用域范围就在函数area形参列表的左右括号之间,提示:由于在函数原型的形参列表中起作用的是形参类型,标识符并不起作用,因此标识符可以省略
- 局部作用域
由以下代码举例;
void func(int a){
int b=a;
cin>>b;
if(b>0){
int c;
}
}
a,b,c都具有局部作用域,只是他们分别属于不同的局部作用域
函数形参列表中形参的作用域,从形参列表中的声明处开始,到整个函数体结束之处为止(a)
函数体内声明的变量,其作用域从声明处开始,一直到声明所在的块结束的花括号为止(b)
而c的作用域是if所在的代码块中(局部作用域)
- 类作用域
类X的成员m具有类有类作用域
1.成员函数体内可以直接访问类成员变量
2.通过表达式x.m或者x::m,其中x::m的方式用于访问静态成员变量
3.通过ptr->m这样的表达式,其中ptr为指向x类中一个对象的指针
- 文件作用域
不在前面各个作用域中出现的声明,就具有文件作用域,始于声明点,结束于文件尾,简言之,全局变量它们在整个文件中都有效
具有文件作用域的也被称为全局作用域
示例
#include<iostream>
using namespace std;
int i=1;
int main(){
return 0;
}
由代码可见,其中i的作用域就
是文件作用域
- 命名空间作用域
在c++中,存在同名变量,函数,和类等情况,为避免发生冲突,让编译器能区分来自不同库的同名实体,c++引入了命名空间的概念,它本质上定义了实体所属的空间,命名空间定义使用namespace关键字,示例如下
namespace namespace_name{
//代码声明
}
而当我们要使用命名空间中的函数,变量等实体的时候,需要命名空间::实体名称或通过using namespace name_space的方式,注意:在using namespace std标准命名空间中实体调用无需加空间前缀
- 限定作用域的枚举类型
定义限定作用域的枚举类型的方式是enum class{},即多了class或struct限定符,此时枚举元素的作用域遵循类作用域,即在枚举类型的作用域外是不可以访问的,相反,在不限定作用域的枚举类型中,枚举元素的作用域与枚举类型本身的作用域相同,
enum color {red,yellow,green}; //不限定作用域的枚举类型
enum color1{red,yellow,green}; //不正确,枚举类型元素重定义
enum class color2{red,yellow,green}; //正确,限定作用域的枚举类型中的元素被隐藏了
color c=red; //正确,color的枚举元素在有效的作用域内
color2 c1=red; //错误,color2 的枚举元素不在有效的作用域内
color c2=color::red; //正确,允许显式的访问枚举元素
color2 c3=color2::red; //正确,使用了color2的枚举元素
2.可见性
定义:程序运行到某一点,能够引用到的标识符,就是该处可见的标识符
作用域可见性的一般规则;
- 标识符要在声明在前,引用在后
- 在同一作用域中,不能声明同名的标识符
- 在没有互相包含关系的不同的作用域中声明的同名标识符,互不影响
- 如果在两个或多个具有包含关系的作用域中声明了同名标识符,则外层标识符在内层不可见
注意:
作用域和可见性不止适用于变量名,也适用于其他各种标识符,包括常量名,用户定义的类型名,函数名,枚举类型等
3.生存期
生存期是什么?
对象(包括简单变量)都有诞生和消失的时候,从对象诞生到消失的这段时间就是它的生存期,生存期可以分为静态生存期和动态生存期
静态生存期
如果对象的生存期与程序运行期相同,我们称它具有静态生存期
在文件作用域中声明的对象都是具有静态生存期,如果要在函数内部的局部作用域中声明具有静态生存期的对象,则要使用关键字static|
例如:static int a;
局部作用域中静态变量的特点是,它并不会随着每次函数的调用而产生一个副本,也不会随着函数返回而失效,即当一个函数返回后,下一次在调用时,该变量还是会保留上一次的值,即使发生了递归调用,也不会为该变量建立新的副本,该变量会在各次调用间共享
动态生存期
除了以上两种静态生存期,其余的对象都具有动态生存期,在局部作用域中声明的具有动态生存期的对象,习惯上也被称为局部生存期对象,局部生存期对象诞生于声明点,结束于声明所在的块执行完毕之时
下面代码的实例
#include<iostream>
using namespace std;
int i=1; //i为全局变量,具有静态生存期
void other(){
static int a=2; //a,b为静态局部变量,具有全局寿命,局部可见,只有第一次进入函数时被初始化
static int b;
int c=10; //c为局部变量,具有动态生存期,每次进入函数时都被初始化
a+=2;
i+=32;
c+=5;
}
int main(){
static int a; //a为静态局部变量,具有全局寿命,局部可见
int b=10; //b,c为局部变量,具有动态生存期
int c=0;