1、 复合语句:指由一对花括号括起来的一组语句,诸如 if 或者 else 后的 {} , for 或者 while 后的 {} 等,在复合语句内定义的变量,作用范围为定义处到复合语句的右花括号 } 结束处。下面代码中的 cout 在标准 c++ 编译器中都会提示出错,原因就在于 cout 都位于复合语句之后。 for(int i=0;i<=5;i++) {; } cout<<i<<endl; while(1) { int j=0; j++;break; } cout<<j<<endl; if(1) { int k=0; k++; } cout<<k<<endl;
2、 如果变量被定义在了函数内(包括形参)而在函数内复合语句之外,则拉悟有仍该变量作用范围为定义处开始到函数体结束。上桢郓羼抱述代码中如果想让 cout 语句生效,则 i、j、k可以在复合语句之前定义。但是细心的同学可能会发现,上述代码在 VC6 中直接编译运行是不会有问题的,难道 VC6 没有遵循标准 c++ 的规范?确实如此,因为 VC6 太过古老了,发布于 98 年,而 c++ 标准是 98 年之后才规范化的,VC6 变量的作用范围最小单元为函数而不是复合语句。上述两种变量我们称为局部变量,作用域之外的代码是无法访问到它们的,当代码运行超过了它的作用范围,它们的内存就会被回收,就不存在了,如果函数被再次调用,则会重新分配内容并初始化。根据该特性可以推出,上述代码执行的结果是 6、1、1 ,如果这段代码属于某个函数,则多次调用该函数的输出总是上述结果,因为每次调用都是新的 i、j、k 。如果一个局部变量使用 static 关键字修饰,则虽然它们的作用域没有发生变化,但是它们的内存是在全局变量区分配的,这就意味着,它们在使用后内存不会被回收,多次使用仍然是同一内存,同时它们只初始化一次,即在第一次调用时会被初始化为初始值。如果上述代码 i 、j、k 的定义前都加入 static ,根据上述特性,可以推出多次调用这段代码后,i 不变永远为 6、j 和 k 则会依次递增为 2、3、4 ....这个特性很有用处,因为这种变量既具备局部变量的高安全性(其他地方无法访问)又具备全局变量的值保留特性。
3、 在函数体外定义的变量称为全局变量,作用范围为整个 c++ 工程,如果在本代码文件内定义语句之后的代码中使用则无需特别操作,直接使用即可,在本代码文件内定义语句之前或者属于同一个工程的其他代码文件内使用时,则需要使用 extern 关键字重新声明一次。下面代码运行结果会是 1int main(){extern int i;i++;cout<<i<<endl;}int i=0;如果 static 修饰了全局变量,则限定此全局变量只在本代码文件内有效,也即有限的全局,其他代码文件即便使用 extern 重新声明了也无效,为什么要设计这么一种作用域呢,因为这样可以有效的避免在不同的代码文件中定义了重名的全局变量而产生冲突,比如大的工程可能多人协作完成,每个人负责一个或者多个功能模块,对应一个或者多个代码文件,此时全局变量命名重名就会很常见,这个特性可以保证即便重名了,别人也无法修改自己定义的全局变量的值。