c++过渡知识2

在这里插入图片描述

嗨咯,大家好,今天阿鑫给大家带来的是c++的过渡知识2,本篇属于c++过渡知识的收尾哦,难度不是很大,下面请大家阅读本篇博客吧!

c++过渡知识2

函数重载

  1. 函数重载的概念
  2. c++如何支持函数重载之名字修饰

初识引用

  1. 引用的概念
  2. 引用特性
  3. 细谈引用和指针权限的放大与缩小

1.函数重载的概念

在c语言中不支持函数重载而在c++中支持函数重载
函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同,常用来处理实现功能类似数据类型不同的问题。
下面我们通过几个例子来认识一下函数重载的概念

#include<iostream>
using namespace std;
void Swap(int* pa, int* pb)
{
	cout << "void swap(int* pa, int* pb)" << endl;
}
void Swap(double* pa,double* pb)
{
	cout << "void swap(double* pa,double* pb)" << endl;
}





int main()
{
	int a = 1, b = 2;
	double c = 0.1, d = 1.1;
	Swap(&a, &b);
	Swap(&c, &d);
	return 0;
}

我们创建了两个同名的函数Swap,这两个函数同时在全局域中,但是由于这两个函数形参部分的参数类型不同,所以构成了重载函数,并且在调用这两个函数时,编译器会自动进行匹配

下面我们结合上一节提到的命名空间域的内容创建三个函数

#include<iostream>
using namespace std;
namespace ZJ1
{
	void Swap(int* pa, int* pb)
	{
		cout << "void swap(int* pa, int* pb)" << endl;
	}
}

namespace ZJ2
{
	void Swap(int* px, int* py)
	{
		cout << "void swap(int* pa, int* pb)" << endl;
	}

}

void Swap(double* pa,double* pb)
{
	cout << "void swap(double* pa,double* pb)" << endl;
}
using namespace ZJ1;
using namespace ZJ2;





int main()
{
	int a = 1, b = 2;
	double c = 0.1, d = 1.1;
	Swap(&a, &b);
	Swap(&c, &d);
	return 0;
}

在这里插入图片描述

当我们在创建了这三个函数时进行调用会报错,下面请大家想想这是由于这两个函数没有构成重载关系的缘故吗?

实则不然,上节我们提到过,不同作用域中的函数和变量是可以同名的,在这里我们这两个函数分别封装在ZJ1和ZJ2两个域中,即使展开了也是处于不同的作用域(注意:展开并不是将函数放在全局处,而是在不指定的情况下,默认编译器也可以去命名空间域中搜索这个函数),并不是因为没有构成重载函数的原因而报错
实际原因是这两个函数在调用过程中会发生歧义,导致编译器既可以调用第一个函数也可以调用第二个函数,所以我们在日常写代码的过程中,要避免产生歧义的这种情况

下面我们介绍一下顺序不同如何形成函数重载

#include<iostream>
using namespace std;
void f(int a, char b)
{
	cout << "f(int a,char b)" << endl;
}

void f(char b,int a)
{
	cout << "f(char b,int a)" << endl;
}




int main()
{
	int a = 1;
	char b = 'abc';
	f(a, b);
	f(b, a);
	return 0;
}

通过上面的代码我们可以看出当对应的参数类型相同时,我们可以通过改变形参的顺序来使之成为函数重载

最后,我们来结合一下缺省函数来构造出一个重构函数

#include<iostream>
using namespace std;
void f(int a = 4)
{
	cout << "f(int a)" << endl;
}

void f()
{
	cout << "f()" << endl;
}




int main()
{
	
	f();
	
	return 0;
}

![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/c09d在这里插入图片描述

同学们请思考一下上面为什么会调用出错,是因为没有构成函数重载吗?
其实还是因为指向不明确,在我们调用函数的时候,编译器发现第一个函数和第二个函数都能够调用,所以会发生调用错误

最后提醒同学们注意的是:返回值不同不能构成重载

2. c++如何支持函数重载之名字修饰

好的在我们介绍完函数重载后,大家有没有过疑问,为什么c语言不支持函数重载,而c++支持函数重载,这是因为我们的c++在编译与链接过程对函数名进行了函数名的修饰,如果有不了解编译与链接过程的同学,可自行阅读博主之前的编译与链接的博客

在想要弄清楚函数重载的秘密,我们先来创建三个文件,以便我们后续的讲解
在这里插入图片描述
在这里插入图片描述

在之前,我们就已经分析了编译与链接各个过程所完成的事情,而我们首先需要注意的是在链接过程之前的过程各个文件都是独自完成的,这点大家先要搞清楚

在这里插入图片描述

我们在stack.cpp定义一个StackInit函数,并且在Test.cpp文件中进行函数的调用,将代码进行反汇编可以得到如图所示的汇编语言
我们可以很明显的看出在call函数的地址之后,才会进行后续的函数调用的指令
(因为:call本质是跳转,函数有一堆要执行的指令,函数地址是第一句指令)
这有点类似数组,有了第一个就能访问剩下的元素

下面我们来思考一下,函数的地址是什么时候获取的,又是如何获取的呢?
我们需要注意的是,在链接过程之前,Test.cpp只有函数声明,可以通过编译,因为语法检查是匹配,但是没有函数的地址
只有有了有函数的定义,才能生成函数一堆汇编指令,第一句指定的地址,才是函数的地址,Stack.cpp->Stack.o中才有函数的定义
聪明的同学已经可以猜到了,因为在链接过程中之前,我们各个文件都是单向的,只有在链接过程时,我们才会进行文件的合并,而由我们之前的知识可以知道,函数的地址会存放在stack.o中的符号表里,在我们链接时,Test.o会拿着StackInit的函数名到Stack.o的符号表中去寻找

在这里插入图片描述

在类似的符号表中,存有每个函数名对应的地址,在我们文件链接完成后,就能拿到函数的地址,从而进行后续的函数调用的一系列操作

在这里插入图片描述
此时我们的小伙伴们,是不是就知道这个错误时如何来的了?没错,就是因为我们缺少了函数的定义,事实也确实如此,我在vs中将函数的定义注释掉,就会得到这样的错误信息

那我们现在给出总结,以及为什么c++能够支持我们的函数重载
链接时:
1、直接用函数名字去查找,是否支持重载,不支持。C语言
2、直接用修饰后的函数名字去查找,就可以支持重载。C++

在这里插入图片描述

我们也可以很清晰的看出,括号里那段内容不一样,就是因为我们的编译器将我们的函数名字进行了修改,从而实现了我们的函数重载

3.引用的概念

引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间
在这里插入图片描述
在这里插入图片描述

我们进行调试可以得出,abcd公用一块空间,我们对任意一个变量进行操作,其他的变量都会随之而改变
在这里插入图片描述
下面我们来简单介绍一下引用的好处和用处

typedef int SLTDataType;

typedef struct SListNode
{
	int val;
	struct SListNode* next;
}SLTNode;

void SLTPushBack(SLTNode** pphead, SLTDataType x);
void SLTPushBack(SLTNode** pphead, SLTDataType x)
{
	assert(pphead);
	SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
	newnode->val = x;
	newnode->next = NULL;
	if (*pphead == NULL)
	{
		*pphead = newnode;
		return;
	}
	SLTNode* ptail = *pphead;
	while (ptail->next)
	{
		ptail = ptail->next;
	}
	ptail->next = newnode;
}

我们在没有接触引用之前,创建一个链表并进行尾插,此时需要传二级指针,这会导致不少同学犯错,从而产生bug,而当我们学习了引用,此时我们就可以将节点的别名传过去,此时可以直接对节点进行操作,不需要再传二级指针,类似

void SLTPushBack(SLTNode*& pphead, SLTDataType x);

此时我也给大家解决一个问题,就是有不少的考研书上会这样写

typedef struct SListNode
{
	int val;
	struct SListNode* next;
}SLTNode,*PNode;
void SLTPushBack(PNode& pphead, SLTDataType x);

这其实是他们进行了两次重命名,第二次是将struct SListNode*重命名为PNode

4.引用的特性

1.引用在定义时必须初始化
2.一个变量可以有多个引用
3.引用一旦引用一个实体,再不能引用其他实体

5. 细谈引用和指针权限的放大与缩小

接下来我们来谈谈引用和指针的权限

int main()
{
	const int m = 0;
	int& n = m;
}

请问同学们,上面的代码能够运行成功吗?
哈哈,很明显不行,因为涉及到了权限的放大,m是只读的,而n变成别名以后可读可写
此时我们有两种改法

const int m = 0;
const int& n = m;


int m = 0;
const int& n = m;

这两种方法都是可行的

那么,这样可以吗?哈哈

int main()
{
	int a = 5;
	const int* p1 = &a;
	int* p2 = p1;
}

也是不行的,因为const修饰*p1,p1不能改,而p2能修改

所以,我们可以得到的是,指针和引用有权限的放大,而普通的拷贝没有权限的放大

好的谢谢大家阅读本篇博客,期待我们的下一次相遇,觉得博主写的还可以的记得订阅点赞收藏加关注哦!哈哈,下次再见啦!

  • 31
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
### 回答1: " PDF 是一种常用的电子文档格式,它可以在不同平台和设备上进行查看和共享。使用 PDF 格式的好处有很多。 首先,PDF 可以保留文档的格式和布局,无论显示在何种操作系统、软件或设备上,用户都可以看到一致的显示效果。这对于保持文档的可读性和可理解性非常重要,尤其是涉及到复杂的排版和图文混排的文档。 其次,PDF 支持多种媒体类型的嵌入,如图片、音频和视频等。这使得 PDF 文档更加丰富和交互,可以通过插入音频和视频来呈现更直观的信息和演示效果。这对于教育和商务等领域非常有用。 此外,PDF 文档还可以进行密码保护和授权,以确保文档的安全性。用户可以设置只有特定人员才能访问和编辑文档,保护敏感信息和知识产权。这对于企业和个人而言,是非常重要的功能特性。 最后,使用 PDF 格式可以减少文件大小,节省存储空间和网络传输带宽。PDF 格式使用无损压缩算法,可以将文件大小大幅缩小,同时不会丢失文件的质量和清晰度。这使得传输和存储文件更加高效,并能节省成本。 综上所述,PDF 格式具有保持文档格式一致性、支持多媒体的插入、提供安全保护、以及文件大小压缩等多种优点。因此,使用 PDF 格式可产生很多积极的影响,并在各种场景下得到广泛应用。 " ### 回答2: Effect C是一款广泛应用于计算机领域的PDF编辑器。PDF(Portable Document Format)是一种用于文档交换和存储的文件格式。它的优点在于跨平台兼容性强、保持文档格式稳定、能够保护文档内容的完整性等。 Effect C作为一款PDF编辑器,具有许多实用的功能。首先,它可以打开和查看PDF文件,使用户能够直观地了解文档的内容。其次,用户可以利用Effect C编辑PDF文件,例如插入、删除或重新排列页面。此外,它还允许用户在PDF文件中添加注释、批注和书签,方便其他用户查看和阅读。 Effect C还提供了一些高级编辑功能。例如,用户可以使用它来合并多个PDF文件,将它们合并成一个文件。此外,它还支持将PDF文件转换为其他格式(如Word、Excel等)和从其他格式(如图片)转换为PDF。这些功能在日常工作和学习中非常实用,能够提高效率和便捷性。 除了编辑功能,Effect C还具备一些保护PDF文件的功能。用户可以使用密码来加密PDF文件,以防止未经授权的访问和修改。此外,Effect C还可以通过数字签名来验证PDF文件的真实性和完整性,确保文档的可信度。 总体而言,Effect C是一款功能强大、易于使用的PDF编辑器。它能够满足用户在PDF文件处理方面的多样需求,并提供了一系列实用工具和功能,帮助用户更好地管理和处理PDF文件。无论是在个人使用还是商务环境中,Effect C都是一款非常有价值的软件。 ### 回答3: Effect C是一种常用的PDF文件格式。PDF是Portable Document Format(便携式文档格式)的缩写,它是一种用于电子文档存储和传输的文件格式,具有跨平台和保持文档格式不变的特点。 Effect C是指PDF文件自带的一种特效,可以为PDF文档添加各种视觉效果和动画效果。通过应用Effect C,用户可以为PDF文档添加平滑过渡效果、淡入淡出效果、放大缩小效果、旋转效果等,使得文档更具吸引力和交互性。这些效果可以增加PDF文件的可读性和可视性,使得文档更加生动和直观。 使用Effect C可以为PDF文档增添各种视觉效果,展示出更丰富的内容和更好的用户体验。例如,在演示文稿中,可以使用平滑过渡效果将幻灯片之间的内容切换得更加流畅,吸引观众的注意力。在电子书中,可以使用淡入淡出效果为页面之间的转换增加过渡效果,提升阅读体验。 然而,需要注意的是,过多或不适当地使用Effect C可能会影响PDF文件的可读性和性能。过多的动画和特效可能会分散读者的注意力,降低他们对文档内容的理解和关注。此外,过多的特效可能会使得文件体积增大,加载和显示速度变慢。因此,在使用Effect C时,应根据实际需求和读者的期望来适度使用,以确保最佳的阅读体验。 综上所述,Effect C是一种为PDF文档添加特效的功能,可以使文档更具吸引力和交互性。合理使用Effect C可以提升PDF文件的可读性和可视性,提供更好的用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值