从C到C++过渡知识 中(为什么C++支持函数重载,而C不支持函数重载)

        感谢大家的阅读,这篇文章我们接着了解C++对于C的一些优化。

函数重载

        了解C++这个特殊用法之前,我们先考虑一个问题,如何交换两个整数。相信大家一定信手捏来,实参传地址而非变量,于是可以写出如下函数。

void Swap(int* p1, int* p2)
{
	int t = *p1;
	*p1 = *p2;
	*p2 = t;
}

        这段代码的逻辑也十分简单,但假如我们要交换两个浮点数呢?我们可以类似上面的思路,把整型改为浮点型写出如下的代码。但在C语言中函数名不可以相同,我们便要将函数名改变。

     

void SwapInt(int* p1, int* p2)
{
	int t = *p1;
	*p1 = *p2;
	*p2 = t;
}

void SwapDouble(double* p1, double* p2)
{
	double t = *p1;
	*p1 = *p2;
	*p2 = t;
}

        我们人的思维是直接的,交换两个数直接就是交换两数,而没考虑类型,但在C中因为传递的参数不同,就必须要设置为两个不同的函数。本贾尼祖师爷也深受其烦,想要优化这种代码,简化我们记忆和使用的负担,将复杂甩手给编译器,于是便有了函数重载的语法。

        下面我们来看下函数重载的官方定义:函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这 些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同。

        于是在C++的语法中,上面的代码便可以写为如下形式。

void Swap(int* p1, int* p2)
{
	int t = *p1;
	*p1 = *p2;
	*p2 = t;
}

void Swap(double* p1, double* p2)
{
	double t = *p1;
	*p1 = *p2;
	*p2 = t;
}

        两个函数的名字都叫Swap,但是形参类型却不同。再函数调用的时候,他会根据函数实参的类型找到对应要调用的函数。

        下面我们看待代码.

#include<iostream>
using namespace std;

void Swap(int* p1, int* p2)
{
	int t = *p1;
	*p1 = *p2;
	*p2 = t;
}

void Swap(double* p1, double* p2)
{
	double t = *p1;
	*p1 = *p2;
	*p2 = t;
}

int main()
{
	int a = 10, b = 5;
	double c = 1.21, d = 2.54;

	cout << "交换前:" << a <<" " << b << endl;
	Swap(&a, &b);
	cout << "交换后:" << a << " " << b << endl;
	cout << "交换前:" << c << " " << d << endl;
	Swap(&c, &d);
	cout << "交换后:" << c <<" "<< d << endl;

	return 0;
}

        上面的代码运行结果如下

        成功的输出了交换后的数字,并且没有报错,如果实在C语言的编译下,这一定是会报错的。但C++引入了函数重载的概念便可以这样写,大大简化了程序员记忆的负担。

        根据函数重载的定义,函数的形参个数,类型或者顺序不同才可以构成重载。下面我们看段代码。

void fun(int a, char ch)
{
	//…………
}

void fun(char ch,int a )
{
	//…………
}

        这两个函数构成重载么?

        答案是他们构成重载因为他们的类型不同,尽管他们的形参个数类型相同!!

        下面我们再看一段代码。

void fun(int a, char ch)
{
	//…………
}

int fun(int a, char ch)
{
	//…………
}

        上面的函数构成重载么?有的读者仔细看发现他们的返回值不一样,可能觉得他们就构成重载了,但这是错误的!!

        上面的两个函数并不构成重载,原因很简单,判断是不是重载首先看函数名,其次看参数不看返回值。他们的函数名相同,参数的个数,顺序,类型也完全相同,故而不构成重载!!有的读者可能有些难以理解,返回值明明也可以作为判断依据,为什么不用呢?那么就继续往下读下一个小章节。

为什么C++支持函数重载,而C不支持函数重载

        聊到这里我们要简单了解下程序运行的过程.我们都知道一个程序的运行包含很多步骤,可以分为 预处理,编译,汇编,链接,以至最后的输出。VS将 预处理,编译,汇编,链接封装运行,所以又被称为高度集成开发的IDE。Linux下便可以观察具体处理细节。每个步骤细节多,在这里我只能简单的介绍每个步骤的使用。

        首先便是预处理,在这个阶段的核心任务是将头文件展开,注释的删除,预处理指令,刚开始的时候不同的.cpp文件是分开处理的。

        紧接着是编译,这个时候对代码进行词义分析,语义分析,词法分析,将C代码转换为汇编代码。在这个时候有个·操作对于我们要讲的十分重要,便是汇总符号!!对于电脑而言,函数也不过是个符号罢了。

        然后是汇编,他将汇编代码翻译为机器码,也就是一连串的二进制01序列,并且形成符号表。

        最后一步是链接,将外部库的代码汇总到main.c文件中,同时将不同的.c文件内容汇总,其中便有符号表汇总,每个符号分配一个地址。

        而我们在调用函数的时候,会首先对于函数名进行修饰然后在符号表中查找。下面我们看段C语言的代码

int Add(int a, int b)
{
	return a + b;
}

void fun(int a,double b,int*p)
{
	//…………
}

        利用Linux查看程序处理结果会得到如下函数名修饰

        

        我们发现它经过处理的函数名只有函数名,没有参数的信息,假如换到cpp环境下呢?

        我们可以明显的发现,函数名修饰后多了许多东西。按照我们实际参数的信息,不难反推出i就是int,pi就算是int*,c就是char,这样参数的信息就加入到了函数名中。当我们调用参数时,他就可以根据重载找到对应函数。我们就可以简单的理解为重载函数,只是在我们看起来是相同的函数,其实对于计算机而言他就是两个完全不同的函数!!

        总结起来C不支持重载的原因是他在编译处理代码的时候没有将函数名加以形参的修饰,区别不出不同函数,而C++进行了对应的修饰,电脑可以识别出你要调用那个函数。

        同时按照这个想法的话,我们把返回值也假如修饰函数名的队伍中也可以,但祖师爷当初设计C++的时候没有制定加入返回值的规则,返回值便不可以作为判断依据。当然祖师爷也有可能是觉得返回值区别的意义不大,便没有加了。我们在学习C++的语法规则中可以不断地问为什么?但一直没有靠谱的回答时,便可能时C++开发时的考虑。C语言完全可以加入函数重载,但那还是C语言么?每个语言都有其特定的优势与局限。

缺省参数

        我们首先看下他的定义.

        缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实 参则采用该形参的缺省值,否则使用指定的实参。他的使用也十分简单,如下图·。

        当我们调用Add函数的时候,由于b参数我们给了他一个初始值,我们便可以调用Add函数时只给她传递一个参数,那么b参数的值就是10,所以打印14.但如果我们传入两个参数,4,5那么b的值就为5,打印9.缺省参数的使用简化了我们记忆代码的负担,弥补了重载函数的一些不足。

        他的语法十分简单,但有几点是我们需要特别注意的。

        首先便是缺省参数必须从右往左依次给,不能跳跃,如下的代码都是错误的。


int Add(int a, int b=10,int c)
{
	return a + b;
}
int Add(int a=10, int b )
{
	return a + b;
}

        C++规定了实参与形参的匹配时从左往右依次匹配,他会默认缺省参数右边都是缺省参数。有的读者可能想从右往左匹配也可以,但C++制定的从左往右依次匹配,我们学习C++要遵守他的规则。

        其次就是缺省参数不能在外部声明和定义时同时出现,当有声明时,缺省参数按照声明执行。如下图

        缺省参数只需要在声明时给初始值,假如只有定义便在定义的时候给。否则就会重定义。

        我们再看段有趣的代码。

#include<iostream>
using namespace std;

int Add()
{
	return 0;
}

int Add(int a=5, int b=10)
{
	return a + b;
}

int main()
{
	cout << Add() << endl;
	cout << Add(4,5) << endl;

	return 0;
}

        上面的代码构成重载么?能运行么?

        首先毫无疑问他们构成重载,他们的参数类型不同。但可以运行么?假如我们调用Add(),他似乎可以调用第一个,也可以调用第二个?我们要明白计算机是不允许有歧义的东西,对于·他来说,1就是1,0就是0.像这种产生了歧义的程序他不会运行,直接报错。

        我们也可以看出他报错的理由是有多个匹配的重载。

        今天的文章就到此结束了,喜欢的点点关注,如果有什么错误欢迎在评论区指出。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/517873.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

轻薄本没有独立显卡如何运行stable diffusion

众所周知&#xff0c;Stable Diffusion WebUI 使用 GPU 模式运行。 一&#xff1a;检查自己显卡 打开任务管理器或者winR 输入dxdiag 查看自己显卡状态 很明显一般轻薄本只会带有集显&#xff0c;不能满足stable diffusion要求所以我们可以使用cup来运行stable diffusion 在…

计算机服务器中了halo勒索病毒怎么办,halo勒索病毒解密流程步骤

随着网络技术的不断应用&#xff0c;企业的生产运营得到了快速发展&#xff0c;越来越多的企业开始利用服务器数据库存储企业的重要信息文件&#xff0c;数据库为企业的生产运营提供了极大便利&#xff0c;但网络技术的不断发展也为企业的数据安全带来严重威胁。近日&#xff0…

用于推荐系统的自监督超图Transformer 笔记

1 Title Self-Supervised Hypergraph Transformer for Recommender Systems&#xff08;Lianghao Xia, Chao Huang, Chuxu Zhang&#xff09;【KDD 2022】 2 Conclusion User behavior data in many practical recommendation scenarios is often noisy and exhibits skewed d…

模糊控制对应关系

一. 基本的一些对应关系 1.论域&#xff1a;X&#xff0c;一般来说取得变量∀x∈X 2.隶属函数&#xff1a;μ( x ) 3.误差&#xff1a;e 4.误差变化率&#xff1a;c&#xff0c;这是对误差求导得到的 5.模糊集常用的量&#xff1a; PL/PB&#xff08;Positive Large/Posi…

Leetcode_2两数相加

文章目录 前言一、两数相加1.1 问题描述1.2 解法一&#xff1a;分别将链表转为数字&#xff0c;然后相加1.3 代码实现1.4 解法二&#xff1a;分别将对应位置数字相加1.5 代码实现 二、使用步骤1.引入库2.读入数据 前言 链表是一种物理内存非连续存储&#xff0c;非顺序的线性数…

C++相关概念和易错语法(3)(类的声明和定义、空指针分析、this指针)

1.类的声明和定义 注意类的声明和定义分离的时候&#xff0c;在定义处要使用域作用限定符&#xff0c;否则函数声明链接时的定位不到函数的定义。 这些成员变量、函数的作用于这个类域&#xff0c;将功能集成在一起&#xff0c;这体现出封装的思想。 在区分类的定义和声明时&…

ModuleNotFoundError: No module named ‘einops‘解决办法

安装对应的库就好 pip install einops -i https://pypi.tuna.tsinghua.edu.cn/simple 拓展——在python中einops模块有什么作用 einops 是一个 Python 库&#xff0c;它提供了一种简洁、易读的方式来操作多维数组&#xff08;通常是 NumPy 数组或 PyTorch 张量&#xff09;。e…

易宝OA ExecuteSqlForDataSet SQL注入漏洞复现

0x01 产品简介 易宝OA系统是一种专门为企业和机构的日常办公工作提供服务的综合性软件平台,具有信息管理、 流程管理 、知识管理(档案和业务管理)、协同办公等多种功能。 0x02 漏洞概述 易宝OA ExecuteSqlForDataSet接口处存在SQL注入漏洞,未经身份认证的攻击者可以通过…

海外媒体发稿:6个高效的旅游业媒体宣发策略为你带来爆炸性增长-华媒舍

随着旅游业的不断发展&#xff0c;媒体宣发策略变得愈发重要。如何让旅游业在众多竞争对手中脱颖而出&#xff0c;成为每个企业所思考的问题。本文将介绍6个高效的旅游业媒体宣发策略&#xff0c;帮助你实现爆炸性增长。 策略一&#xff1a;社交媒体营销 社交媒体已成为当今社…

【文献分享】机器学习 + 分子动力学 + 第一性原理 + 热力学性质 + 微观结构

分享一篇关于机器学习 分子动力学 第一性原理 热学性质&#xff08;密度、比热容、导热率和粘度&#xff09; 微观结构的文章。 感谢论文的原作者&#xff01; 关键词&#xff1a; 1. Deep potential 2. Machine learning 3. Molecular dynamics 4. Microscopic structu…

Vue3_2024_8天【vue2中的标签ref和vue3中的标签ref的区别】

第一&#xff1a;Vue 2 中的 ref 在 Vue 2 中&#xff0c;ref 主要用于在模板中注册引用信息。它可以用在html标签上或&#xff08;子&#xff09;组件上。一旦标签元素或组件被渲染&#xff0c;你就可以通过 this.$refs 来访问它。 <template> <div ref"myDiv&…

【00】【solidity最新教程】-简介

Solidity 是一门面向合约的、为实现智能合约而创建的高级编程语言。这门语言受到了 C&#xff0c;Python 和 Javascript 语言的影响&#xff0c;设计的目的是能在以太坊虚拟机&#xff08;EVM&#xff09;上运行。 Solidity 是静态类型语言&#xff0c;支持继承、库和复杂的用…

idea Springboot校园新闻系统VS开发mysql数据库web结构java编程计算机网页源码maven项目

一、源码特点 springboot 校园新闻发布系统是一套完善的信息系统&#xff0c;结合springboot框架和bootstrap完成本系统&#xff0c;对理解JSP java编程开发语言有帮助系统采用springboot框架&#xff08;MVC模式开发&#xff09;&#xff0c;系统具有完整的源代码和数据库&a…

公众号申请上限怎么提升

一般可以申请多少个公众号&#xff1f;众所周知&#xff0c;在2013年前后&#xff0c;公众号申请是不限制数量的&#xff0c;后来企业开始限制申请50个&#xff0c;直到2018年的11月tx又发布&#xff0c;其中个人主体可申请公众号由2个调整为1个&#xff0c;企业主体由50个调整…

eBay买家号注册下单容易死号?是什么原因导致?

随着电子商务的迅猛发展&#xff0c;跨境电商平台eBay日益成为众多消费者和商家的首选。然而&#xff0c;自去年下半年以来&#xff0c;eBay推出的新规则给买家号的注册带来了前所未有的挑战。许多新用户反映&#xff0c;在注册eBay买家号后&#xff0c;往往遭遇刚注册就被冻结…

Linux 用户、用户组 useradd、groupadd等详解

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《Linux &#xff1a;从菜鸟到飞鸟的逆袭》 &#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、前言 1、Linux的起源与发展 2、Linux在现代计算机领域…

Android Studio gradle-8.4 配置 GreenDao

1.配置项目下的build buildscript {repositories {mavenCentral()}dependencies {classpath ("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.0")classpath ("org.greenrobot:greendao-gradle-plugin:3.3.1") // 使用最新版本} } 2.配置app下的build i…

书生浦语训练营2期-第二节课笔记作业

目录 一、前置准备 1.1 电脑操作系统&#xff1a;windows 11 1.2 前置服务安装&#xff08;避免访问127.0.0.1被拒绝&#xff09; 1.2.1 iis安装并重启 1.2.2 openssh安装 1.2.3 openssh服务更改为自动模式 1.2.4 书生浦语平台 ssh配置 1.3 补充&#xff08;前置服务ok…

JavaScript中堆栈内存管理机制及其在深拷贝与浅拷贝场景中的应用与解析

一.堆栈的定义 1.栈是一种特殊的线性表。其特殊性在于限定插入和删除数据元素的操作只能在线性表的一端进行。 结论&#xff1a;后进先出&#xff08;Last In First Out&#xff09;&#xff0c;简称为LIFO线性表。 栈的应用有&#xff1a;数制转换&#xff0c;语法词法分析&…

VGA 时序与实现

1. VGA 时序标准 小梅哥视频链接&#xff1a;23A VGA成像原理与时序详解_哔哩哔哩_bilibili 行扫描时序图 场扫描时序图具体参数自己查表 2. 640*480 分辨率 VGA 控制器时序分析 2.1 行扫描区间构成 H Sync Time H Bach PorchH Left BorderH Data TimeH Right BorderH…