第9课 - 函数重载分析(下)

第9课 - 函数重载分析(下)

1. 重载与指针

1.1 下面的函数指针将保存哪个函数的地址?

    

1.2 函数重载遇上函数指针

    将重载函数名赋值给函数指针时:

  (1)根据重载规则挑选与函数指针参数列表一致的候选者

  (2)严格匹配候选者的函数类型与函数指针的函数类型  (这里不仅需要匹配参数类型,还需要匹配返回值的类型,不然编译会出错!!!

 1 #include <stdio.h>
 2 #include <string.h>
 3 
 4 int func(int a)
 5 {
 6     return a;
 7 }
 8 
 9 int func(int a, int b)
10 {
11     return a + b;
12 }
13 
14 int func(const char *s)
15 {
16     return strlen(s);
17 }
18 
19 typedef int (*pFunc)(int);    // 注意typedef后面的分号
20 
21 int main(void)
22 {
23     int c = 0;
24     pFunc p = func;
25     
26     c = p(1);    // 根据pFunc指针的类型选择对应的重载函数
27     
28     printf("c = %d\n", c);
29 
30     return 0;
31 }
函数重载 VS 函数指针

1.3 注意事项

  (1)函数重载必然发生在同一个作用域中

  (2)编译器需要用参数列表函数类型进行函数选择  【函数指针和参数的间接关系,函数指针中包含了返回值和参数类型的信息】

  (3)无法直接通过函数名得到重载函数的入口地址

2. C++ 和 C 的相互调用

2.1 C++ 和 C 的相互调用

  (1)实际工程中C++ 和C 代码相互调用是不可避免的

  (2)C++ 编译器能够兼容C 语言的编译方式

  (3)C++ 编译器会优先使用C++ 编译的方式

  (4)extern 关键字能强制让C++ 编译器进行C 方式的编译

    

【编程实验】C++ 调用C 函数

1 int add(int a, int b);
add.h
1 #include "add.h"
2 
3 //该文件的编译,得到目标文件add.o
4 //gcc -c add.c
5 
6 int add(int a, int b)
7 {
8     return a + b;
9 }
add.c
 1 #include <stdio.h>
 2 
 3 //该文件的编译
 4 //g++ main.cpp add.o
 5 
 6 #ifdef __cplusplus
 7 extern "C" {
 8 #endif
 9 
10 //C++中以C的方式编译:将add的函数名就是目标名
11 #include "add.h"
12 
13 #ifdef __cplusplus
14 }
15 #endif
16 
17 int main()
18 {
19     int c = add(1, 2);
20 
21     printf("c = %d\n", c); //3
22 
23     return 0;   
24 }
main.cpp

2.2 如何保证一段C代码只会以C的方式被编译?

  (1)__cplusplus 是 C++ 编译器内置的标准宏定义

  (2)__cplusplus 的意义:确保C代码以统一的C方式被编译成目标文件

    

【编程实验】C 调用 C++ 函数 (其中的C++ 函数由gcc 编译)

 1 //该文件的编译,得到目标文件add.o
 2 //g++ -c add.c
 3 
 4 #ifdef __cplusplus
 5 extern "C" {
 6 #endif
 7 
 8 //C++中以C的方式编译:add的函数名就是目标名
 9 int add(int a, int b);
10 
11 #ifdef __cplusplus
12 }
13 #endif
add.h
 1 #include "add.h"
 2 
 3 //该文件的编译,得到目标文件add.o
 4 //g++ -c add.c
 5 
 6 #ifdef __cplusplus
 7 extern "C" {
 8 #endif
 9 
10 //C++中以C的方式编译:add的函数名就是目标名
11 int add(int a, int b)
12 {
13     return a + b;
14 }
15 
16 #ifdef __cplusplus
17 }
18 #endif
add.cpp
 1 #include <stdio.h>
 2 #include "add.h"
 3   //编译方式:
 4   //gcc main.c add.o
 5 int main()
 6 {
 7     int c = add(1, 2);
 8 
 9     printf("c = %d\n", c); //3
10 
11     return 0;   
12 }
main.c

【编程实验】C 调用 C++ 函数 (其中的C++ 函数由g++ 编译)

  ①假设别人提供了编译好的cpp的头文件和.o目标文件,但其中的函数是以C++方式编译的,很明显函数名是用C++方式命名的。我们的C文件里不方便使用这个的函数名。

  ②解决方案:做一个C++的封装层,对其中的函数进行一个封装,然后再用extern  "c"编译这些封装层中的函数,最后就可以在C文件中使用了。

 

  ★ 其他人编写的C++代码,其中的函数名是用C++方式编译的,但只提供的.h和.o文件

1 int add(int a, int b);
add.h
1 #include "add.h"
2 
3 //编译命令:g++ -c add.cpp
4 
5 int add(int a, int b)
6 {
7     return a + b;
8 }
add.cpp
1 int addEx(int a, int b);
addEx.h
1 #include "add.h"
2 
3 //编译命令:
4 //g++ -c addEx.cpp
5 
6 extern "C" int addEx(int a,int b)
7 {
8     return add(a, b);
9 }
addEx.cpp
 1 #include <stdio.h>
 2 #include "addEx.h"
 3 //编译命令:
 4 //gcc main.c addEx.0 add.o
 5 
 6 int main()
 7 {
 8     int c = addEx(1, 2);
 9 
10     printf("c = %d\n", c); //3
11 
12     return 0;   
13 }
main.c主文件

2.3 注意事项

  (1)C++ 编译器不能以C 的方式编译重载函数,即如果在extern  "C"块里有两个同名的函数里,则会编译失败。

  (2)编译方式决定函数名被编译后的目标名

     ⅰ:C++ 编译方式将函数名参数列表编译成目标名

     ⅱ:C 编译方式只将函数名作为目标名进行编译

3. 小结

  (1)函数重载是C++ 对 C 的一个重要升级

  (2)函数重载通过函数参数列表区分不同的同名参数

  (3)extern关键字能够实现C 和 C++ 的相互调用

  (4)编译方式决定符号表中的函数名的最终目标名

 

转载于:https://www.cnblogs.com/shiwenjie/p/7169678.html

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

常见窗函数的C语言实现及其形状,适用于单片机、DSP作FFT运算

目录源码WindowFunction.cWindowFunction.h使用形状三角窗巴特利特窗巴特利特-汉宁窗布莱克曼窗布莱克曼-哈里斯窗博曼窗切比雪夫窗平顶窗高斯窗海明窗汉宁窗纳托尔窗Parzen窗矩形窗&#xff08;模拟&#xff09;效果无窗汉宁窗平顶窗平台&#xff1a;Windows 10 20H2 Visual …

.net Json JavaScriptSerializer JsonHelper类

结合.net 的JavaScriptSerializer 类实现Json数据处理 调用1&#xff1a; Model.Users m BLL.UsersBLL.GetUserById(Convert.ToInt32(id));string result "";if (m ! null)result JsonHelper.ObjectToJSON(m);context.Response.Write(result); 调用2&#xff…

C语言实现的FFT与IFFT源代码,不依赖特定平台

目录源码FFT.cFFT.h使用方法初始化输入数据FFT 快速傅里叶变换解算FFT结果使用python绘制FFT波形IFFT 快速傅里叶逆变换解算IFFT结果Windows 10 20H2 Visual Studio 2015 Python 3.8.12 (default, Oct 12 2021, 03:01:40) [MSC v.1916 64 bit (AMD64)] :: Anaconda, Inc. on …

在51单片机上使用递归的注意事项

目录问题应对措施原理普中51-单核-A2 STC89C52 Keil uVision V5.29.0.0 PK51 Prof.Developers Kit Version:9.60.0.0 问题 在Keil C51中直接使用递归会报如下警告&#xff1a; recursive call to non-reentrant function 为了提高运行效率&#xff0c;C51采用静态分配局部变量…

C盘瘦身:QQ文件的清理及Group2文件夹

目录问题解决方法Windows 10 20H2 TIM 问题 最近C盘被撑爆了 使用SpaceSniffer一扫发现QQ的文件中有个Group2文件夹占了我17G 但使用QQ自带的个人文件夹清理却扫不到&#xff0c;据说直接删除会丢失近期所有群聊的聊天图片 解决方法 在这个地方找到了大神fsz1987给出的解…

获取ArcGIS安装路径

在要素类进行符号化时&#xff0c;使用axSymbologyControl需要安装路径下的Style文件路径&#xff0c;在AE9.3VS2008中是这样的&#xff1a; Microsoft.Win32.RegistryKey regKey Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SOFTWARE\\ESRI\\CoreRuntime",…

【51单片机快速入门指南】3.2:定时器/计数器

目录快速使用硬知识传统51单片机 CPU 时序的有关知识&#xff08;12T&#xff09;51 单片机定时器原理51 单片机定时/计数器结构定时器/计数器0/1定时器/计数器0和1的相关寄存器控制寄存器工作模式寄存器工作模式模式0(13位定时器/计数器)模式1(16位定时器/计数器)模式2(8位自动…

sublime_text 3 注册序列号

为什么80%的码农都做不了架构师&#xff1f;>>> ----- BEGIN LICENSE ---- Andrew Weber Single User License EA7E-855605 813A03DD 5E4AD9E6 6C0EEB94 BC99798F 942194A6 02396E98 E62C9979 4BB979FE 91424C9D A45400BF F6747D88 2FB88078 90F5CC94 1CDC92DC 845…

【51单片机快速入门指南】3.2.1:PWM、呼吸灯与舵机

目录硬知识PWM&#xff08;脉冲宽度调制&#xff09;基本原理脉宽调制分类上机实战呼吸灯main.c中断服务函数修改TIM.c中的中断服务函数效果开发板电路分析舵机控制舵机控制方法main.c中断服务函数修改中断服务函数舵机测试程序main.c效果普中51-单核-A2 STC89C52 Keil uVisio…

Proteus仿真单片机:51单片机的仿真

目录新建工程调试在Proteus中编写程序导入Keil生成的Hex程序Windows 10 20H2 Proteus 8 Frofessional v8.9 SP2 Keil uVision V5.29.0.0 PK51 Prof.Developers Kit Version:9.60.0.0 新建工程 设置名称和路径 下一步 下一步 选择系列、控制器和编译器 双击MCU设置主频 …

Linux 命令行输入

这几天刚刚接触到Linux&#xff0c;在windows上安装的VMWare虚拟机&#xff0c;Centos7。安装什么都是贾爷和办公室的同事帮忙搞定的。 在虚拟机界面&#xff0c;按快捷键CtrlAltEnter&#xff0c;可以全屏显示Linux界面&#xff0c;再按一次则退出全屏。 如何在Linux里输入命令…

【51单片机快速入门指南】2.5:并行I/O扩展与8255A

目录硬知识单片机I/O扩展基础知识I/O接口电路的功能速度协调输出数据锁存数据总线隔离数据转换增强驱动能力单片机并行扩展总线并行扩展总线的组成80C51单片机并行扩展总线I/O编址技术可编程并行接口芯片82558255硬件逻辑结构口电路总线接口电路A组和B组控制电路中断控制电路82…

win 下 apache2.4 +tomcat7 集群

为什么80%的码农都做不了架构师&#xff1f;>>> 反正每次来做一个不熟悉的东西&#xff0c;就是各种的search ,前一次去做过一个apache的东西&#xff0c;各种蛋疼&#xff0c;各种不能用。好多的东西也是比较旧了的咯。 这次结合前辈的各种东借西拿&#xff0c;总…

Proteus仿真单片机:PIC18单片机的仿真

目录新建工程ProteusMPLAB X IDE调试Windows 10 20H2 Proteus 8 Frofessional v8.9 SP2 MPLAB X IDE v5.45 新建工程 Proteus 下一步 下一步 选择芯片、编译器 搭建实验电路 MPLAB X IDE MPLAB X IDE 新建工程 选择独有项目 选择芯片 选择编译器 配置工程名称、路…

Realm学习总结

参考博客: http://www.jianshu.com/p/096bec929f2a http://www.cnblogs.com/ilyy/p/5648051.html 参考的博客介绍很详细,我就不写了..写了一个简单的学习的demo. GitHub地址: https://github.com/PengSiSi/RealmDemo 代码如下: // // ViewController.m // RealmDemo // // C…

with(nolock)的用法

with(nolock)的介绍 大家在写查询时,为了性能,往往会在表后面加一个nolock,或者是with(nolock),其目的就是查询是不锁定表,从而达到提高查询速度的目的。 当同一时间有多个用户访问同一资源,并发用户中如果有用户对资源做了修改&#xff0c;此时就会对其它用户产生某些不利的影…

【PIC18单片机学习笔记】一、程序的烧录

目录编程器烧录软件烧录准备程序main.cpic18.h烧录效果Windows 10 20H2 PICkit 3 v3.10 MPLAB X IDE v5.45 PIC18F46J50 编程器 所用编程器为PICkit 3.5 按图示连接好编程器和开发板 烧录软件 所用烧录软件为PICkit 3 v3.10 初次使用需要给编程器更新固件&#xff0c…

ASIHttpRequest:创建队列、下载请求、断点续传、解压缩

ps&#xff1a;本文转载自网络&#xff1a;http://ryan.easymorse.com/?p12 感谢作者 工程完整代码下载地址&#xff1a;RequestTestDownload1 可完成&#xff1a; 下载指定链接的zip压缩文件存放在Documents目录下支持断点续传显示下载进度解压到指定目录—————————…

熊仔科技Steamduino PIC18F46J50主控板 部分原理图

目录连接情况原理图实物图Proteus 8 Frofessional v8.9 SP2 从学长那嫖的&#xff0c;本来貌似是要用来做写字机器人的&#xff0c;后面学长换成Arduino UNO了。 网上找不到资料&#xff0c;用万用表简单测了测没有丝印部分的连接情况 连接情况 RD2/PMD2/RP19 USR_LED…

【51单片机快速入门指南】3.3:USART 串口通信

目录快速使用硬知识串行口相关寄存器串行口控制寄存器SCON和PCON串行口数据缓冲寄存器SBUF从机地址控制寄存器SADEN和SADDR与串行口中断相关的寄存器IE和IPH、IP串行口工作模式串行口工作模式0&#xff1a;同步移位寄存器串行口工作模式1&#xff1a;8位UART&#xff0c;波特率…