C++作用域与函数重载的实现
作者:Bebop 时间:2022-04-30 06:28:30
1、作用域
1.1 作用域的作用
作用域——scope
通常来说,一段程序代码中所用到的名字并不总是有效/可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。
简单来说,作用域的使用减少了代码中名字的重复冲突,增强了程序的逻辑性与可靠性
1.2 作用域的分类
C++变量根据定义位置的不同,具有不同的作用域:
全局作用域
局部作用域
文件作用域
全局变量具有全局作用域
全局变量只需在一个源文件中定义,就可以作用于所有的源文件
其他不包括全局变量定义的源文件需要用extern关键字再次声明这个全局变量
静态局部变量具有局部作用域。它只被初始化一次,从第一次初始化直到程序运行结束都一直存在,他和全局变量的区别在于全局变量对所有的函数都是可见的,而静态局部变量只对定义自己的函数体始终可见
局部变量也只有局部作用域,他是自动对象,他在程序运行期间不是一直存在,而是只在函数执行期间存在,函数的一次调用结束后,变量就被撤销,其所占用的内存也被收回
静态全局变量也具有全局作用域,他与全局变量的区别在于如果程序包含多个文件的话,他作用于定义它的文件里,不能作用到其他文件里,即被static关
键字修饰过的变量具有文件作用域。这样即使两个不同的源文件都定义了相同的静态全局变量,也是不同的变量
1.3 static 、const
1.3.1 static
静态函数只能被所在的cpp文件调用,不同cpp文件可以有相同的静态函数名字。静态函数与普通函数作用域不同,仅在本文件。内部函数:只在当前源文件中声明和定义的函数称为内部函数(static);对于可在当前源文件以外使用的函数,应该在头文件中说明,或者进行extern全局声明。static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝
static作用于局部变量时
在局部变量声明前加static = 静态局部变量,存储方式改变了,局部变量是动态存储,静态局部变量是静态存储方式,也就是改变了它的生存期由函数内部或者块内部变为文件作用域,虽然并不是真正的“文件作用域”,声明在函数内,但是在函数外部无法访问,只是为了避免重名冲突
static作用于全局变量时
在全局变量声明前加static = static全局变量,全局变量本身是静态存储方式,静态全局变量也是静态存储方式,在存储方式上无区别,无改变,主要区别在于非静态全局变量的作用于是整个源程序(由多个源程序组成的话,在各个源文件中都有效);静态全局变量限制了作用域,只在定义该变量的源文件中有效(全局作用域->文件作用域),可避免在其他文件中引起错误,static变量只初始化一次,下一次依照上一次的值。
总结:
静态局部变量扩大了局部变量的生存期,静态全局变量缩小了全局变量的作用域
1.3.2 const
const在C语言和C++中存在差异,先来解释其中的区别
在C语言中,Const修饰的变量只是告诉编译器该变量是一个只读的变量,不能通过该变量改写器内存空间中的值,但是其本质上还是一个变量,既然是变量,就会有内存地址,因此可以通过指针间接修改该地址空间的值,举例如下
在C++中Const修饰的变量被称为常量,其值存放在常量表中,在使用常量时,编译器回到常量表中查询对应的常量,并将其替换,这部分没有涉及内存分配,因此对其取地址是没有意义的,但是当我们非要对该常量去地址时,则编译器会为其临时分配一个内存,并将常量值存入该临时内存中。事实上,在C++中规定必须用const修饰的指针来指向const修饰的常量。虽然可以使用强制转换的方式,对Const修饰的常量进行去地址,并将其赋值给一个非Const修饰的指针(最好不要这样做),但打这个指针上的任何改动只会影响到临时分配的内存空间,而不会影响到原常量上
2、 域作用限定符
作用域限定符为两个冒号::,其作用是通知编译器从作用域限定符左侧名字所示的作用域中寻找右侧名字
即指定访问指定空间的成员
2.1 空间域的命名
namespace NewSpace
{
int time = 3600;
...
}//命名可嵌套
2.2 指定空间访问
指定空间 ::操作
实例:
std :: cout << "" << std :: endl//std::代表访问标准库
用全局展开的标准库就可以避免在cout endl前指定标准库也是一个方法,但是对于可能产生的冲突,我们还是采取指定空间访问的方法
2.3 全局展开
将某空间在某个局部或者全局展开,就可以自由使用操作
using namespace ...
2.4 部分展开
部分展开只需要展开我们需要用的操作,比如:
using std :: cout
3、函数重载
在C语言程序的编写中,可能会用到几个功能相同的函数,但是有些细节却不同。
例如:交换两个数的值其中包括(int, float,char,double)这些个类型,我们通常借助不同的命名来完成区分
void Swap1(int* a, int* b);
void Swap2(float* a, float* b);
void Swap3(char* a, char* b);
void Swap4(double* a, double* b);
我们可以看出这样的代码不美观而且不便,于是在C++中人们提出可以用一个函数名定义多个函数,也就是所谓的函数重载
3.1 函数重载规则
函数名称必须相同
参数列表必须不同(个数不同、类型不同、参数排列顺序不同等)
函数的返回类型可以相同也可以不相同
仅仅返回类型不同不足以成为函数的重载
实例:
#include<iostream>
using namespace std;
int main()
{
int max(int a, int b, int c);
int max(int a, int b);
int a = 10;
int b = 20;
int c = 30;
cout << max(a, b, c) << endl;
cout << max(a, b) << endl;
return 0;
}
int max(int a, int b, int c)
{
if (b > a)
a = b;
if (c > a)
a = c;
return a;
}
int max(int a, int b)
{
return (a > b) ? a : b;
}
来源:https://blog.csdn.net/qq_64893500/article/details/128857494
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
详解Java对象的强、软、弱和虚引用+ReferenceQueue
Java使用excel工具类导出对象功能示例
关于Eureka的概念作用以及用法详解
![](https://img.aspxhome.com/file/2023/3/122253_0s.jpg)
有关Java中的BeanInfo介绍
![](https://img.aspxhome.com/file/2023/5/57955_0s.jpg)
Spring 事务事件监控及实现原理解析
spring cloud alibaba Nacos 注册中心搭建过程详解
![](https://img.aspxhome.com/file/2023/9/106169_0s.jpg)
IntelliJ IDEA 好用插件之analyze inspect code详解
![](https://img.aspxhome.com/file/2023/9/67649_0s.png)
MyEclipse设置Console输出到文件的实现方法
![](https://img.aspxhome.com/file/2023/3/73023_0s.png)
Java可变个数形参的方法实例代码
![](https://img.aspxhome.com/file/2023/2/62372_0s.png)
C# Math中常用数学运算的示例详解
详解Java中Collections.sort排序
Unity UGUI实现卡片椭圆方向滚动
![](https://img.aspxhome.com/file/2023/2/77292_0s.jpg)
SpringBoot Entity中枚举类型详细使用介绍
![](https://img.aspxhome.com/file/2023/8/59218_0s.png)
C# 中的动态创建组件(属性及事件)的实现思路及方法
Java受检异常的一些思考
深入java内存查看与分析详解
浅谈JVM垃圾回收有哪些常用算法
C语言 MD5的源码实例详解
浅谈Spring Boot 开发REST接口最佳实践
![](https://img.aspxhome.com/file/2023/0/62420_0s.png)