首页/新闻资讯/正文详情

C++深入浅出讲解函数重载

发布时间:2026/11/13 1:09:41 来源:云帆数科 栏目:资讯中心
C++深入浅出讲解函数重载
前言自然语言中一个词可以有多重含义人们可以通过上下文来判断该词真实的含义即该词被重载了。比如以前有一个笑话国有两个体育项目大家根本不用看也不用担心。一个是乒乓球一个是男足。前者是“谁也赢不了”后者是“谁也赢不了”函数重载1.1 函数重载的概念函数重载它是函数的一种特殊情况C允许在同一作用域中同一作用域中声明几个功能类似的同名函数函数重载的关键是函数的参数列表也称为“函数特征标”这些同名函数的形参列表(参数个数、类型和顺序(不同类型的顺序))必须不同常用来处理实现功能类似数据类型不同的问题函数重载也是多态的一种多态指的是“有多种形式”12345678910111213141516171819202122232425//C语言不支持重载C支持重载intAdd(intleft,intright){returnleftright;}doubleAdd(doubleleft,doubleright){returnleftright;}intAdd(intleft,doubleright){returnleftright;}intAdd(doubleleft,intright){returnleftright;}intmain(){Add(10, 20);Add(10.0, 20.0);Add(10, 20.0);Add(10.0, 20.0)return0;}下面两个函数属于函数重载吗1234567891011121314shortAdd(shortleft,shortright){returnleftright;}intAdd(shortleft,shortright){returnleftright;}intmain(){Add(10, 20);Add(10, 20);return0;}代码解析上述代码中的两个函数不属于函数重载因为重载的形参列表(参数个数、类型和顺序)必须不同函数重载与函数返回值的类型无关并且在函数调用时也是无法识别它的1.2 函数重载的意义意义在C语言中想要定义多个不同类型交换数据的子函数需要不同的函数名来命名比如SweapA、SweapB…等等1234567891011121314151617181920voidSweapA(int*pa,int*pb){inttemp *pa;*pa *pb;*pb temp;}voidSweapB(double*pa,double*pb){doubletemp *pa;*pa *pb;*pb temp;}intmain(){inta 10, b 20;doublec 10.0, d 20.0;SweapA(a, b);SweapB(c), d);return0;}但是在C中通过函数重载只需要命名一次就可以了虽然跟C语言一样要重复定义函数但是后面会学到函数模板后可以很好的解决这个重复定义问题1234567891011121314151617181920voidSweap(int*pa,int*pb){inttemp *pa;*pa *pb;*pb temp;}voidSweap(double*pa,double*pb){doubletemp *pa;*pa *pb;*pb temp;}intmain(){inta 10, b 20;doublec 10.0, d 20.0;Sweap(a, b);Sweap(c), d);return0;}1.3 名字修饰(name Mangling)名字修饰(name Mangling)C为了跟踪每一个重载函数它都会给这些函数指定一个私密身份使用C编译器编写函数重载程序时C编译器将执行一些奇特的操作 — — ---名称修饰 或 名称矫正它根据函数原型中指定的形参对每个函数名进行加密对参数数目和类型进行编码添加的一组符号符合随函数形参列表而异修饰时使用的约定函数名随编译器而异为什么C支持重载而C语言不支持呢在C/C中一个程序要运行起来需要经历以下几个阶段预处理、编译、汇编、链接预处理.i文件展开、宏替换、条件编译、去注释编译.s检查语法是否正确生成汇编代码汇编.o将汇编代码转化成二进制的机器码链接a.out生成符号表找调用函数的地址链接匹配合并到一起实际我们的项目通常是由多个头文件和多个源文件构成当前a.cpp中调用了b.cpp中定义的Add函数在编译后链接前的处理阶段a.o的目标文件中没有Add的函数地址因为Add是在b.cpp中定义的所以Add的地址在b.o中。那么怎么办呢链接器看到a.o调用Add但是没有Add的地址就会到b.o的符号表中找Add的地址然后链接到一起链接时面对Add函数链接器会使用哪个名字去找呢这里每个编译器都有自己的函数名修饰规则在Linux下使用gcc和g编译器演示函数名被修饰后的名字采用C语言编译器编译后结果反汇编结论在Linux下采用gcc编译完成后函数名字的修饰没有发生改变采用C编译器编译后结果反汇编结论在Linux下采用g编译完成后函数名字的修饰发生改变编译器将函数参数类型信息添加到修改后的名字中总结gcc的函数修饰后名字不变。而g的函数修饰后变成_Z函数长度函数名类型首字母C语言没办法支持重载因为同名函数没办法区分。而C是通过函数修饰规则来区分只要参数不同修饰出来的名字就不一样就支持了重载Windows下名字修饰规则结论对比Linux会发现windows下C编译器对函数名字修饰非常奇怪但道理都是一样的扩展学习C/C函数调用约定和名字修饰规则C函数重载C/C的调用约定接下来再演示一个例子f.h#include stdio.hvoid f(int a, double b);void f(double b, int a);f.cpp#include f.hvoid f(int a, double b);{printf(%d %lf\n, a, b)}void f(double b, int a);{printf(%lf %d\n, b, a)}Test.cpp#include f.hint main(){f(1, 2.222);f(2.222, 1);return 0;}编译后生成汇编指令链接时生成符号表Linux下gC编译器的命名Linux下gccC编译器的命名1.4 extern C有时候在C工程中可能需要将某些函数按照C的风格来编译但是大多数情况下是C工程需要将某些函数按照C的风格来编译C可以调用CPP的静态/动态库而CPP也可以调用C的静态/动态库extern “C”是告诉编译器它所声明的函数是C的库要用C的链接方式去调用静态库或动态库那么CPP是怎么调用C中的静态/动态库呢vs2022演示首先我们用C来生成一个静态库或动态库123456789101112131415161718192021222324252627Test.h#include stdio.hvoidPrintArray(int* p,intn);//显示数组内容voidInsertSort(int* p,intn);//插入排序Test.C#include Test.hvoidInsertSort(int* p,intn){for(inti 0; i n - 1; i){intend i;inttmp p[end 1];while(end 0){if(tmp p[end]){p[end 1] p[end];--end;}else{break;}}p[end 1] tmp;}}配置类型改成静态库后生成解决方案就得到后缀.lib文件了在CPP项目中添加新的库目录这个库是你生成的静态库的路径增加新的依赖项依赖项为生成静态库的文件名后缀Test.lib做完这些准备后我们来进行编译程序编译后我们发现链接阶段时出现了错误原因是C调用C时它们之间的函数命名规则名称修饰不同我们需要C中的extern C来解决extern “C”是告诉编译器它所声明的函数是C的库要用C的链接方式去调用静态库或动态库1234567891011121314151617181920externC{//../是在当前目录的上一个目录中找文件#include ../../Test/Test/Test.h}#include iostreamusingnamespacestd;voidTestInsertSort(){intArray[] { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };InsertSort(Array,sizeof(Array) /sizeof(Array[0]));for(inti 0; i 10; i)cout Array[i] ;cout endl;}intmain(){TestInsertSort();return0;}如果C想调用CPP的静态或动态库呢C调用CPP库时也会遇到名称修饰的问题这里需要对CPP的名称修饰规则改成C的规则这里我们需要用到条件编译来解决问题12345678910111213141516171819202122232425262728293031323334353637383940Test.h#include stdio.h#ifdef __cplusplus#define EXTERN_C extern C#else#define EXTERN_C#endifEXTERN_CvoidPrintArray(int* p,intn);EXTERN_CvoidInsertSort(int* p,intn);Test.cpp#include Test.hvoidPrintArray(int* p,intn){for(inti 0; i n; i){printf(%d , p[i]);}printf(\n);}voidInsertSort(int* p,intn){for(inti 0; i n - 1; i){intend i;inttmp p[end 1];while(end 0){if(tmp p[end]){p[end 1] p[end];--end;}else{break;}}p[end 1] tmp;}}感谢大家支持到此这篇关于C深入浅出讲解函数重载的文章就介绍到这了

相关推荐

如何快速掌握SubtitleEdit:免费开源字幕编辑工具的完整指南
如何快速掌握SubtitleEdit:免费开源字幕编辑工具的完整指南

如何快速掌握SubtitleEdit:免费开源字幕编辑工具的完整指南 【免费下载链接】subtitleedit the subtitle editor :) 项目地址: https://gitcode.com/gh_mirrors/su/subtitleedit SubtitleEdit是一款功能强大的免费开源字幕编辑软件,专为视频创作者… · 2026/10/16 13:46:25

卫星阀门焊漏一滴毁一颗星?精密激光封焊三道关
卫星阀门焊漏一滴毁一颗星?精密激光封焊三道关

所谓航天精密组件的密封焊接,就是用高能量密度的激光束对卫星阀门壳体、传感器壳体等关键部件进行气密性封装,确保焊缝在太空真空、极端温变、强振动环境下实现零泄漏。2026年,中国商业航天进入高密度发射周期。长征八号新一代运载火箭实现批… · 2026/11/2 0:43:10

激光焊接设备怎么选?90%的人算漏三笔隐性成本
激光焊接设备怎么选?90%的人算漏三笔隐性成本

所谓激光焊接设备的全生命周期成本(TCO),不只是报价单上的设备价格,而是从设备到货开始调试,到5-8年后退役或升级期间,你为这台设备花掉的每一分钱的总和——包括调试期的停产损失、换型时的产能浪费&#… · 2026/10/20 16:30:42

新乡应届生考低压电工作业培训班多久拿证?避开这些坑才能稳稳上岗
新乡应届生考低压电工作业培训班多久拿证?避开这些坑才能稳稳上岗

新乡应届生考低压电工作业培训班多久拿证?避开这些坑才能稳稳上岗 你是不是也在为找工作发愁? 急需特种作业证才能上岗找工作 ,尤其是像低压电工这类实操性很强的工种,没有证连面试机会都没有。别急,今天就给你讲讲新乡应届工程类毕业生怎么考低压电工… · 2026/11/13 1:09:03

安阳电工证复审地点怎么选?怕考不过白交培训费?多久拿证才靠谱?
安阳电工证复审地点怎么选?怕考不过白交培训费?多久拿证才靠谱?

安阳电工证复审地点怎么选?怕考不过白交培训费?多久拿证才靠谱? 怕考不过白交培训费?你不是一个人。现在安阳电工证复审地点越来越多,培训机构鱼龙混杂,很多学员担心花了钱,结果考试没过,培训费打了水漂。其实只要选对地方, 多久拿证… · 2026/11/13 1:09:03

中高级电工证难吗真实经历告诉你怎么避坑
中高级电工证难吗真实经历告诉你怎么避坑

中高级电工证难吗真实经历告诉你怎么避坑 不知道去哪报名怕被中介坑,这几乎是每个想考中高级电工证的人都会遇到的难题。我自己就是漯河一家工厂的转岗人员,从一线操作工转到技术岗,第一件事就是考中高级电工证,当时真的被各种培训机构的花言巧语搞得晕头… · 2026/11/13 1:09:03

嘉定哪里考高压电工证?真实经历告诉你别怕考不过
嘉定哪里考高压电工证?真实经历告诉你别怕考不过

嘉定哪里考高压电工证?真实经历告诉你别怕考不过 怕考不过白交培训费?你不是一个人。去年在嘉定参加高压电工证考试的王师傅,就是交了3000块培训费,结果因为没复习好,笔试直接挂了,心情糟透了。他的真实经历让我意识到,备考高压电工证,真的不能靠… · 2026/11/13 1:09:03

广州电工证科目二实操继续教育学时要求
广州电工证科目二实操继续教育学时要求

电工证科目二实操太难?工地太忙根本没时间复习考试,真实经历告诉你怎么破 工地太忙根本没时间复习考试,这几乎是所有一线工人的真实写照。我认识的老李在三门峡工地干了八年电工,去年想考广州电工证科目二实操,结果因为白天忙得脚不沾地,晚上还得照顾孩… · 2026/11/13 1:09:03

清远市电工证报考怎么报名?外省证能不能转过来?一文讲透!
清远市电工证报考怎么报名?外省证能不能转过来?一文讲透!

清远市电工证报考怎么报名?外省证能不能转过来?一文讲透! 之前考的证在外省能不能转过来?这可能是很多准备报考清远市电工证的小伙伴最关心的问题。别急,今天我来给你详细说说清远市电工证报考怎么报名,包括外省证件的转接问题,还有备考重点、考试技巧… · 2026/11/13 1:08:02

电工证丢失还能补吗?千万别踩坑,丢了证等于失业
电工证丢失还能补吗?千万别踩坑,丢了证等于失业

电工证丢失还能补吗?千万别踩坑,丢了证等于失业 你正在找工作,但手里的电工证突然丢了,这下怎么办?别急,先别慌, 电工证丢失还能补吗 ?答案是肯定的,但 千万别踩坑 ,补办流程如果不了解,可能会耽误你上岗、甚至影响到你的收入。… · 2026/11/12 14:09:01

电力电缆作业证直播报名入口与办理流程良心建议
电力电缆作业证直播报名入口与办理流程良心建议

电力电缆作业证直播报名入口与办理流程良心建议 你是不是也担心学历不高报不了名?别急,今天就给你讲讲 电力电缆作业证直播 的报名流程和那些你必须知道的干货, 良心建议 在这里,别错过。 电力电缆作业证直播报名需要什么条件?… · 2026/11/11 19:07:25

英德电工证报考费多少钱,怕考不过白交培训费?看完这篇别再踩坑
英德电工证报考费多少钱,怕考不过白交培训费?看完这篇别再踩坑

英德电工证报考费多少钱,怕考不过白交培训费?看完这篇别再踩坑 怕考不过白交培训费?英德电工证报考费多少钱,你真的了解吗?现在市面上培训机构五花八门,价格参差不齐,很多人一不小心就花了冤枉钱,结果还考不过。别急,今天就来给你说清楚英德电工证的… · 2026/11/12 23:27:43

维修电公用考电工证吗 在哪考最靠谱
维修电公用考电工证吗 在哪考最靠谱

维修电公用考电工证吗 在哪考最靠谱 工地太忙根本没时间复习考试,你是维修电工,天天在项目上跑,连抽个空背个题都难。那问题来了—— 维修电公用考电工证吗 ?答案是: 必须考 。尤其是在当前施工行业,没有电工证,连进场都可能被拦下。而且,… · 2026/11/13 0:00:08

电工证是不是可以登高?含金量和证书范围你必须知道的事
电工证是不是可以登高?含金量和证书范围你必须知道的事

电工证是不是可以登高?含金量和证书范围你必须知道的事 证书过期了不知道怎么复审延期,这事儿很多人遇到过,尤其是像你这样在郑州金水区做劳务班组负责人,手里握着几十个工人的证书,稍微一疏忽,就可能影响工程进度和公司信誉。特别是电工证是不是可以登… · 2026/11/13 0:00:08

鸡西电工证哪家下证快官方报名入口怎么找
鸡西电工证哪家下证快官方报名入口怎么找

鸡西电工证哪家下证快官方报名入口怎么找 你是不是也担心 学历不高怕报不上名 ?别急,今天我就来跟你说说, 鸡西电工证哪家下证快 ,还有 官方报名入口 到底怎么找,别让那些“代办”“代考”耽误了你的机会。… · 2026/11/13 0:00:08

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/12 4:35:34

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/12 4:36:01

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/12 21:15:21

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码