6.1.1 C++词法作用域
C++中有六种作用域:
(1)块作用域
(2)函数作用域
(3)文件作用域
(4)整个程序作用域
(5)类作用域
(6)名字空间作用域
块作用域也是右开闭花括号定界的,块作用域和函数作用域的区别是函数有参数和名字。在程序执行时候调用函数时 ,就进入了函数作用域,块作用域是不能被调用的。在执行了位于前面的语句之后,块才能被执行。
#include<iostream> using namespace std; struct Account{ long num; double bal; }; double getBalance(Account a) { Index z; double total = a.bal;return total; } int main() { typedef int Index; Index const MAX =5; Index i,count =0; Account a[MAX]; double total =0; while(true) { long num[MAX] = {800123456,800123123,800123333,-1}; double amounts[MAX] = {1200,1500,1800}; if(num[count] == -1)break; a[count].num = num[count]; a[count].bal = amounts[count]; count++; } cout<<"Data is loaded \n\n"; for(i =0;i<count;++i) { long temp = a[i].num; cout <<temp<<endl; } for(i =0;i<count;++i) { double temp = a[i].bal; cout<<temp<<endl; } for(i=0;i<count;++i) { total += getBalance(a[i]); } cout<<endl<<"Total of balance $"<<total<<endl; return 0; }
在这里,类型Account的作用域是整个文件,在定义的地方到该源文件的结束它都是可知的。类型Account的变量可以定义在这个作用域中任何地方。在这个作用域中不管用Account做什么事情,都是不对的。
类型Index有着函数的作用域,其定义的地方直到main()函数的闭括号为止它都是可知的。类型Index可以定义在main()中,但不能定义在另一个作用域。
函数getBalance()有着程序作用域。在程序作用域中。其他对象都不能命名为getBalance.
(1)块变量:定义在块的开花括号后(或者块的的中间),从定义的地方开始,直到块的闭花括号结束都是可见的。在上面程序中,块变量是在main()中的第一个循环中定义的amount[]和num[],在main()中第二个循环中定义 的变量temp和第三个循环中定义的变量temp.
(2)函数变量 :类似与块变量,但他们的作用域是一个声明了的函数,而不是个无名的他们定义在函数体中(在开花括号后,或者在中间),从定义的地方开始直到该函数的闭括号为止他们都是可见的。
(3)函数形式参数:定义在函数头部且在整个函数体中可见。这就意味着可能与函数中定义的变量发生冲突。
(4)全局变量:有着文件作用域——他们定义在文件中以及位于任何函数之外,且从其定义的地方开始直到文件结束都是有效的。
6.1.3在独立的作用域中使用相同的名字
定义在不同的作用域中的名字不会相互发生冲突(有某些列外);
这里的“不同”实际上需要做进一步的解释这些不同的作用域应该如何相互冠梁使得同一个名字可以在不同的作用域中用于不同的目的?
俩个作用域不相交(没有共同的语句)的块是不同的。而且,他们是各自独立的,在文件或在函数作用域中相互跟随(直接或者间接)的无名快是独立的,而且可以完全不同的目的而定义并使用相同的目的。在独立的作用域中定义的名字不会相互冲突。
6.1.4在嵌套的作用域中使用相同的名字
另外一种不同的作用域的而理性与嵌套的概念有关。C++是一种块结构语言。这意味着他的作用域可以丛刺法上相互嵌套,那就是一个作用域的括号全部至于另一个作用域的括号之中。注意,不同的作用域可以是独立的(一个作用域在另一个作用域开始之前结束)或嵌套的(一个作用域在另一个作用域之中)。但是他们不能交叉。
大多数C++chengxu使用嵌套作用域。一个无名快可以嵌套在另一个无名快或者一个函数之中。一个无名快不能直接嵌套在文件作用域中,因为控制将不能到达它:他需要函数头。一个函数可以嵌套在文件作用域中,它不能嵌套在另一个函数中。列如如下代码:
int main() { double getBalance(Account a) { double totl = a.bal; return total; } }
因为getBalance()隐藏在main()函数中,仪以使其名字的作用域将不再文件作用域里。因此当getBalance名字有其他的使用时将不会运气冲突。