第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

第9课 - 函数重载分析(下)相关推荐

  1. Python第十课(函数3)

    Python第十课(函数3)    >>>转到思维导图>>>转到中二青年 闭包函数 1.定义在函数内部的函数 2.内部函数内部函数引用了外部函数名称空间作用域的名字 ...

  2. Python第八课(函数1)

    Python第八课(函数1)    >>>转到思维导图>>>转到中二青年 函数的返回值 函数内要想返回给调用者值 必须用关键字return 不写return:函数默 ...

  3. 【梅哥的Ring0湿润插入教程】重磅第三课:Ring0下的PE Loader及重加载内核秒杀一切内核级钩子(上篇)...

    [梅哥的Ring0湿润插入教程] Email:mlkui@163.com 转载请注明出处,谢绝喷子记者等,如引起各类不适请自觉滚J8蛋! 第三课:Ring0下PE Loader及重加载内核绕过一切内核 ...

  4. 第9课:IDEA下的spark程序开发

    第9课:IDEA下的spark程序开发 1.下载IntelliJ IDEA: http://www.jetbrains.com/idea/ 选择社区版,要在centos上安装,需要下载.TARGZ,解 ...

  5. MySQL中常见的单行函数(下)

    MySQL中常见的单行函数(下) 一.转换函数 Date_format(date,format) 将日期转换成字符串(类似Oracle中的to_char()) Str_to_date(str,fo ...

  6. 新课改实践下美术课程的新教学观

    新课改实践下美术课程的新教学观<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" ...

  7. 回旋矩形C语言,C语言回旋函数解释下,该如何处理

    当前位置:我的异常网» C语言 » C语言回旋函数解释下,该如何处理 C语言回旋函数解释下,该如何处理 www.myexceptions.net  网友分享于:2013-06-08  浏览:30次 C ...

  8. 职教高中计算机专业知识,新课改背景下计算机专业教学(职教)三维目标设计初探...

    吴勇 摘要:课改是基础教育课程改革的简称.把学生当成课程建设的主体,并以学生为中心建立自主.合作.探究的学习模式.課改具体内容就是从应用教材,教育模式,教育理念到考核模式所发生的有目的.有标准.有成果 ...

  9. (五)Kotlin简单易学 基础语法-初始函数(下)

    (五)Kotlin简单易学 基础语法-初始函数(下) 函数内联 ➢ lambda可以让你更灵活的编写应用,但是,灵活也要付出代价的. ➢在JVM上,你定义的lambda会以对象实例的形式存在,JVM会 ...

最新文章

  1. kafka 主动消费_SpringBoot2 整合Kafka组件,应用案例和流程详解
  2. ArcGIS Engine效率探究——要素的添加和删除、属性的读取和更新(转载)
  3. 3星|《掌控大趋势》:全球当前政治经济形式的资料汇编整理,对未来的预测很少,也缺乏独到深刻的见解...
  4. python资源百度网盘-bypy-百度网盘Python客户端 linux
  5. python 计算两个日期相差多少个月
  6. ubuntu18.04的ifconfig输出没有ip地址
  7. PHP的void mixed
  8. Use BAdI to link appointment to a given opportunity during creation
  9. Tyvj 1176 火焰巨魔的惆怅
  10. 计算机等级考试试题在线测试,计算机等级考试上机练习题.pdf
  11. python函数进阶小结_python之函数进阶
  12. 数字化方法基础(四)_矩阵操作
  13. matlab基于模型的测试与验证,基于模型的测试和验证工具——Reactis
  14. matlab 图例自定义,matlab中如何自定义图例_常见问题解析
  15. notepad++官网下载(官网无法访问的解决办法)
  16. 根据卡号查询银行卡信息
  17. 数据库导出换行mysql_数据库导出excel 换行
  18. 支付宝签名php,支付宝快捷支付 PHP服务端签名
  19. 基于昇腾AI异构计算架构CANN的通用目标检测与识别一站式方案初体验
  20. postgresql兼容MySQL on update current_timestamp

热门文章

  1. Debian 系统安装 Nagios 服务器监控端
  2. 什么原因成就了一位优秀的程序员?(转)
  3. ReportViewer不连接数据库,自定义DataSet导出到报表
  4. servlet核心API的UML图
  5. sharepoint配置问题解决方案
  6. node搭建服务器,写接口,调接口,跨域
  7. 3D场景中选取场景中的物体。
  8. 1.0 算法本机调试方法
  9. 深入学习Redis(4):哨兵
  10. LAMP介绍-MySQL安装