標識符的作用域
一、作用域的定義
作用域是一個標識符在程序正文中有效的區域,即定義的變量可以被應用的有效區域。
二、作用域的分類
1.函數原型作用域
函數原型作用域是C++程序中最小的作用域。在函數原型聲明時形式參數的作用范圍就是函數原型作用域。
例如,對於如下函數聲明:
double area (double radius);
標識符radius的作用范圍就在函數area形參列表的左右括號之間,在程序的其他地方不能引用這個標識符。從這里就可看出,radius的作用域稱為函數原型作用域。
2.局部作用域
首先,我們看到書上的例子
void fun(int a){
int b=a;
cin>>b;
if(b>0){
int c;
...
}
}
在這個函數中,形參列表里聲明了形參a,在函數體內聲明了變量b,並用a的值初始化b。接下來,在if語句內,又聲明了變量c。a,b和c都具有局部作用域,只是它們分別屬於不同的局部作用域。
形參的作用域:從形參列表中的聲明開始,到整個函數體結束之處為止。
函數體內聲明變量的作用域:從聲明處開始,一直到聲明所在的塊結束的大括號為止。
看了書上的例子后,再看以下的示例:
#include <iostream>
using namespace std;
int main ()
{
// 局部變量聲明
int a, b;
int c;
// 實際初始化
a = 10;
b = 20;
c = a + b;
cout << c;
return 0;
}
運行結果如圖。
3.類作用域
對於類X的某成員m的,它具有類作用域。訪問m的方式有如下3種:
(1)如果X中沒有聲明同名的局部作用域標識符,那么可以直接訪問m。
Student student;
student.show();
(2)使用x.m或X::m。這是訪問對象成員的最基本方法。注意,X::m的方式用於訪問類的靜態成員。
void Student::show(){
cout<<Student::name<<endl;
}
(3)使用ptr->m,其中ptr為指向X類的一個對象的指針。
Student *student = new Student();
student->show();
4.命名空間作用域
命名空間的語法形式:
namespace 命名空間名(
命名空間名內的各種聲明
)
使用方法:using語句
using 命名空間名::標識符名;
using namespace 命名空間名;
第一種,使得在當前作用域中可以直接引用該標識符,不能使用命名空間內的其他標識符;
第二種則可以直接引用該命名空間內的任何標識符。
命名空間的嵌套:
namespace OuterNs{
namespace InnerNs{
class SomeClass(...);
}
}
想要引用其中的SomeClass類十分復雜,需要使用OuterNs::InnerNs::SomeClass的語法形式。
三、實例驗證
1.實驗目的:用實驗證明該知識點的使用
2.實驗過程:
#include <iostream>
using namespace std;
int i; //在全局命名空間中的全局變量
namespace Ns{
int j; //在Ns命名空間中的全局變量
}
int main(){
i=5; //為全局變量i賦值
Ns::j=6; //為全局變量j賦值
{
using namespace Ns; //使當前塊中可以直接引用Ns命名空間的標識符
int i; //局部變量,局部作用域
i=7;
cout<<"i="<<i<<endl; //測試
cout<<"j="<<j<<endl; //測試
}
cout<<"i="<<i<<endl; //測試
return 0;
}
運行結果:
結果分析:
代碼中,變量 i 具有命名空間作用域,它屬於全局命名空間,有效范圍直到文件尾。在主函數開始處給 i 賦初值5,接下來又聲明了同名變量並賦初值7。第一次輸出的結果是7,這是因為具有局部作用域的變量 i 把具有命名空間作用域的 i 隱藏了,於是具有命名空間作用域的 i 變得不可見。
直到第一個塊運行結束,輸出的 i 的值為7,這說明具有局部作用域的 i 不在有效范圍之內了,現在處在有效范圍內的變量只有具有命名空間作用域的那個變量。
而對於j,它具有命名空間作用域,它被聲明在命名空間 Ns 中,在主函數中通過 Ns::j 的方式引用,為其賦值,接下來在塊中,通過 using namespace Ns 使得該命名空間的標識符可以在該塊中被直接引用,因此輸出時可以直接使用標識符 j 。