SailorMoon-z

导航

笔记——标识符的作用域

标识符的作用域

作用域:标识符在程序正文中有效的区域

有以下分类:

  • 函数原型作用域
  • 局部作用域(块作用域)
  • 类作用域
  • 命名空间作用域

1. 函数原型作用域

在函数原型声明时形参作用范围就是函数原型作用域。

另:函数原型作用域是C++程序中最小的作用域

例子:

	double area(double radius);//函数声明

图片显示错误:

解释:radius的作用域就在左右括号之间。(注意: 函数原型形参列表起作用的是形参类型,标识符可以省略。但是为了代码可读性强,需要写上标识符)

作用: 增强代码可读性

2.局部作用域(局部变量)

函数列表形参的作用域: 从形参声明处 → 整个函数结束

函数体内声明的变量: 声明处 → 大括号

例子:

		#include<iostream>
		using namespace std;
		
		void fun(int para) {	//定义一个测试函数,para为形参,作用域到该函数大括号为止
			cout << "para = " << para<<endl;//可以打印出para = 0
			int test1 = 1;		//定义test1,作用域从此到所在块大括号为止
			if (test1) {     
				cout << "--------大括号开始" << endl;
				int test2 = 2;		//定义test2,作用域是从此到所在块大括号为止
				cout << "test1 = " << test1 << endl;   //在test1作用域范围内,所以可以访问
				cout << "test2 = " << test2 << endl;
				cout << "--------大括号结束" << endl;
			}
			cout << "test1 = " << test1 << endl;	
			cout << "para = " << para << endl;	//分别可以打印出test1 和 para,理解作用域
		
		}
		//测试函数
		int main() {
			fun(0);
			return 0;
		}

截屏结果:

如果在标识符作用域外访问会报错。如:

若在if里添加 int test1 = 3; 则会屏蔽了上一级的test1

结果:

所以在使用时明确使用目的,定义局部还是全局标识符。

作用:

  • 防止数据被污染。如果不想if里的数据被外部使用,可以在if里面定义,这样在if外部访问会报错。
  • 节省内存空间。具有局部作用域的变量也成局部变量,局部变量使用完后会被销毁,腾出空间。

3.类作用域

类可以看做是一组有名成员的集合。

访问类X员有三种方式:

  • 若果X的成员函数没有声明同名的局部作用域标识符,那么可以直接访问成员m。若果有同名,可以通过this->m访问。
  • x.m 或者 X::m访问,X::m用于访问静态成员。
  • ptr->m访问,其中ptr是指向一个类的指针。

例子:

		#include<iostream>
		using namespace std;
		
		class X {  //定义一个类X
		public:
			void fun1();
			void fun2(int m);
		private:
			int m = 3;
		};
		void X::fun1() {
			cout << "m =" << m << endl;//没有同名标识符,直接访问
		}
		void X::fun2(int m) {  //通过X::fun2访问
			cout << "传入的m = " << m << endl;  //有同名标识符,打印传入的参数
			cout << "访问类的m = " << this->m << endl;
		}
		int main() {
			X x;
			x.fun1();  //!!没有参数也要加括号
			x.fun2(6);
			cout << "指针访问-----------------" << endl;
			X* ptr = &x; //给指针赋初值
			ptr->fun1();
			ptr->fun2(5);
			return 0;
		}

输出:

4.命名空间作用域(全局变量)

作用:相当于文件夹的作用。

在开发中通常由不同模块构成,不同模块由不同人员开发,可能存在重名而引起错误。命名空间就可以解决这一问题,例如“南京路”,上海有南京路,武汉也有南京路,到底是哪一个南京路呢?如果在南京路前加上武汉或者上海这样的“命名空间”就可以区分了。

语法:

	namespace 命名空间名{     //定义
	
		命名空间的声明(函数声明,类申明,全局的数据......)
	

	}
	命名空间名::标识符号      /使用

	//在另一个作用域使用,c++提供了using语句
	using 命名空间名::标识符号;	   //暴露指定标识符
	using namespace 命名空间名;    //暴露该命名空间所有标识符

例子:

新建一个头文件.h ,输入全局声明

namespace.h

	#pragma once  /*表示该文件只运行一次,,因为文件中如果加载了很多东西,每次需要的时候都要加载的话会浪费运行速度。*/
	#include<iostream>
	using namespace std;
	#ifndef MYHEAD_H    /*编译预处理,防止命名空间嵌套时重复命名*/
	#define MYHEAD_H  
	namespace mynamespace {
		class Tangle {
			private:
				double lon, wid; //只是外部不能访问,可以进行修改
			public:
				void caltangle(int lon = 1, int wid = 1); //声明caltangle函数,并给lon wid 默认参数
		};
	}
	#endif 

再新建一个文件.cpp实现caltangle函数,计算长方形的面积

namespace.cpp

	#include"./namespace.h"//引入头文件
	#include<iostream>
	
	using namespace std;
	using namespace mynamespace;//暴露mynamespace所有标识符
	//实现caltangle函数,计算长方形的面积
	void Tangle::caltangle(int lon=1, int wid=1) {
		long area = lon * wid;
		cout << "arae = " << area;
	}

测试

main.cpp

	#include<iostream>
	#include<cmath>
	using namespace std;
	
	#include"./namespace.h"  //引入头文件
	using namespace mynamespace;  //暴露mynamespace所有标识符
	//测试
	int main() {
		Tangle tag;
		int lon, wid;
		cout << "enter two number:";
		cin >> lon >> wid;
		tag.caltangle(lon, wid);
		return 0;
	}

结果:

这样把一长段代码分成声明,实现,测试三个模块。好处是:重复性更好,管理性更好,可读性更好,更可靠的代码。

posted on 2019-09-26 18:05  SailorMoon-z  阅读(568)  评论(0编辑  收藏  举报