归纳编程学习的感悟,
记录奋斗路上的点滴,
希望能帮到一样刻苦的你!
如有不足欢迎指正!
共同学习交流!
🌎欢迎各位→点赞 👍+ 收藏⭐ + 留言📝
人生就像骑单车,要想平衡就得往前进!
一起加油!
目录
一、前言:
二、不同的作用城:
⭐例:局部作用域范围的标识符。
🔑说明:
归纳起来,变量的作用域范围主要包括以下几类:
⭐例:不同作用域示例:
☘️注意:
⭐例:暴露指定标识符。
☘️注意:
三、作用域嵌套:
⭐例:内部作用域与外部作用域示例标识符的不同作用域:
四、总结:
五、共勉:
一、前言:
数据的共享和保护是程序员在编写大型复杂程序时要考虑的主要问题之一,如何在程序内部实现数据最大限度的共享,提高编程效率,同时又能避免非法操作或误操作给数据造成的破坏?C++为此提供了很好的支持机制。
二、不同的作用城:
作用域是指一个标识符在程序中的哪些地方是有效的,C++中的很多作用域是通过大括号来
进行限定的。
程序里有的标识符只是局部使用,此时把它定义成局部变量比较合适一一只是自己使用,不需要传递给其他函数,如果完全暴露出来,导致其他位置对其进行了非法篡改,反而不是很好。但是如果一个标识符在很多地方(如很多函数)要用到,为了避免函数间繁琐地传递参数带来的不便,我们习惯将这样的一些变量设置为全局的,此时变量的作用域就是整个文件。
⭐例:局部作用域范围的标识符。
#include<iostream>
using namespace std;
int main(){int sum=0;for(int val=1;val<=10;val++){sum+=val;}cout<<"sum of 1 to 10 inclusive is :"<<sum<<endl;return 0;
}
🔑说明:
本程序统计1到 10 所有整数之和。程序中定义了三个标识符,main、sum 和val.注意函数名也是一个标识符; main 是在大括号外面定义的,和其他在大括号外面定义的标识符一样,它具有全局作用域。具有全局作用域的标识符一旦被声明以后就能够在程序中任何位置被访问。main 函数体内部定义的 sum 变量的作用域从定义开始到 main函数体结束,由于 sum 标识符具有块作用域,因此在 main 函数外部不能访问它;变量val在 for 语句中定义的,只能在 for 语句中使用。
因此,可在第一次要使用变量的时候再定义,这样既可以很方便地查到变量定义的位置,也可以提高程序的可读性。
归纳起来,变量的作用域范围主要包括以下几类:
- ⚡局部作用域;
- ⚡函数原型作用域;
- ⚡类作用域;
- ⚡文件作用域;
- ⚡命名空间作用域。
⭐例:不同作用域示例:
#include<iostream>
using namespace std;int reused=40;//reused具有文件作用域 class Date{//Date具有文件作用域 private:int date;//date具有类作用域,在类内部可以随意访问 public:void Putdate(int pd);//pd仅在函数声明中有效 int Getdate(){return date; }
};void Date::Putdate(int pd){//pd仅在Putdate中有效 date=pd;
}int main(){Date d1;//d1具有局部作用域,仅在main函数中有效 int m;cin>>m;//cin具有命名空间作用域 d1.Putdate(m);cout<<d1.Getdate();//cout具有命名空间作用域 return 0;
}
在具体了解命名空间作用域之前,有必要先学习命名空间的概念。大型程序开发通常由不同的模块组成,不同的模块可能是由不同的开发小组开发的。不同模快中可能都会定义大量全局的标识符,比如一些类名和函数名等。当系统将它们合成在一起时,会引起不可避免的命名冲突,同样地,在开发大型软件时,也可能会引用不同开发者开发的库,这些库也有可能存在全局标识符冲突的问题。为了避免冲突,可以定义不同的命名空间,只要在个命名空间下没有同名的全局标识符,就可以避免冲突。命名空间的声明方法如下:
name NS_Example{
class.complex;
complex add(const complex&a, const complex 6b);
……//各种声明:类,变量,函数,模板
//和语句块类似,结尾没有分号
}
和其他标识符的命名规则一样,命名空间的名称在其定义的作用域范围内必须是唯一的,命名空间可以定义在全局作用域中,也可以定义在另一个命名空间中。它不能定义在类中或函数中。
☘️注意:
命名空间声明末尾没有分号。
不同的命名空间确定了不同的作用域,不同的命名空间可以包含名称相同的成员。在命名空间内部可以直接引用当前命名空间中声明的标识符,如果需要引用其他命名空间的标识符,需要加上其他命名空间的名称。
目前所给的示例程序中使用到的库都在标准命名空间 std 之下;程序中所用到的 cin、cout和endl等都是在 std 中定义的。所以在引用这些标识符时需要在前面加上命名空间,如 std::cin.std::cout 和 std:endl 等,有时在标识符前面总是加上这样的命名空间限定会使语句显得过于冗长。C++会使用 using 语句解决这一问题,使用 using 语句进行声明后,可以使编程人员在引用某个命名空间中的标识符时,不用在前面加上繁琐的前缀。using 语句主要有两种形式,如下所示:
using 命名空间名::标识符名;
using namespace 命名空间名;
第一种形式将指定的标识符暴露于当前的作用域,使程序员在当前作用域中可以直接引用该标识符;
第二种形式则将指定命名空间中的所有标识符暴露于当前作用域,使程序员在当前作用域中可以直接引用该命名空间内的任意标识符,前面很多示例采用的都是这种方式。
⭐例:暴露指定标识符。
#include<iostream>
using std::cin;int main(){int i;cin>>i;//正确,cin是命名空间的cin cout<<i;//错误,没有cout的引用说明,必须写完整的前缀 std::cout<<i;//正确,表明使用的是std命名空间的cout return 0;
}
☘️注意:
每次引用声明后面一定要以分号结束,头文件中最好不要包含引用声明,头文件会被其他文件所包含,在头文件中包含命名空间引用声明可能会引起命名冲突等问题。
三、作用域嵌套:
一个作用域可以包含其他一些作用域,被包含的作用域称为内部作用域,包含的作用域称为外部作用域。
在某个作用域声明了一个标识符后,这个作用域嵌套的所有内部作用域都可以访问这个标识符;在外部作用域定义的标识符也可以在内部作用域中重新定义。
⭐例:内部作用域与外部作用域示例标识符的不同作用域:
#include<iostream>
using namespace std;int reused=42;//reused具有全局作用域 int main(){int unique=0;//unique具有块作用域 cout<<reused<<" "<<unique<<endl;//输出42 0 int reused=0;//定义新的局部变量reused后屏蔽了全局的reused cout<<reused<<" "<<unique<<endl;//访问局部reused,输出0 0 cout<<::reused<<" "<<unique<<endl;//通过::指定访问全局的reused,输出42 0 return 0;
}
为了说明内部作用域和外部作用域问题,我们定义了同名的全局变量和局部变量,在实际编程时尽量不要定义同名的全局变量和局部变量,否则会降低程序可读性。
四、总结:
- 作用域是指一个标识符在程序中的哪些地方是有效的。
- 注意函数名也是一个标识符。
- 命名空间的名称在其定义的作用域范围内必须是唯一的,命名空间可以定义在全局作用域中,也可以定义在另一个命名空间中。
- 命名空间声明末尾没有分号。
- 不同的命名空间确定了不同的作用域,不同的命名空间可以包含名称相同的成员。
- 使用 using 语句进行声明后,可以使编程人员在引用某个命名空间中的标识符时,不用在前面加上繁琐的前缀。
- 每次引用声明后面一定要以分号结束,头文件中最好不要包含引用声明,头文件会被其他文件所包含,在头文件中包含命名空间引用声明可能会引起命名冲突等问题。
- 为了说明内部作用域和外部作用域问题,我们定义了同名的全局变量和局部变量,在实际编程时尽量不要定义同名的全局变量和局部变量,否则会降低程序可读性。
五、共勉:
以上就是我对C++共享和保护——(1)作用域的理解,希望本篇文章对你有所帮助,也希望可以支持支持博主,后续博主也会定期更新学习记录,记录学习过程中的点点滴滴。如果有不懂和发现问题的小伙伴,请在评论区说出来哦,同时我还会继续更新对C++共享和保护的理解,请持续关注我哦!!!