C++中的函数重载问题

C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的
形参列表(参数个数 或 类型 或 顺序)必须不同
为什么C++支持函数重载,而C语言不支持函数重载呢?
在C/C++中,一个程序要运行起来,需要经历以下几个阶段:预处理、编译、汇编、链接

从源代码到可执行程序的过程
(1)源代码.c文件先经过预处理器,生成一个中间文件.i文件
(2).i文件经过编译生成汇编.s文件
(3).s的汇编文件经过汇编器生成.o的目标文件
(4).o的目标文件经过链接器生成.elf可执行程序

预处理  C 预处理器不是编译器的组成部分,但是它是编译过程中一个单独的步骤。简言之,C 预处理器只不过是一个文本替换工具而已,它们会指示编译器在实际编译之前完成所需的预处理。我们将把 C 预处理器(C Preprocessor)简写为 CPP。

所有的预处理器命令都是以井号(#)开头。它必须是第一个非空字符,为了增强可读性,预处理器指令应从第一列开始。

常用的预处理命令如下:

#define              定义一个预处理宏
#undef             取消宏的定义

#if                      编译预处理中的条件命令, 相当于C语法中的if语句
#ifdef                判断某个宏是否被定义, 若已定义, 执行随后的语句
#ifndef             与#ifdef相反, 判断某个宏是否未被定义
#elif                  若#if, #ifdef, #ifndef或前面的#elif条件不满足, 则执行#elif之后的语句, 相当于C语法中的else-if
#else                与#if, #ifdef, #ifndef对应, 若这些条件不满足, 则执行#else之后的语句, 相当于C语法中的else
#endif              #if, #ifdef, #ifndef这些条件命令的结束标志.
defined          与#if, #elif配合使用, 判断某个宏是否被定义

#include            包含文件命令
#include_next   与#include相似, 但它有着特殊的用途

#line                标志该语句所在的行号
#                      将宏参数替代为以参数值为内容的字符窜常量
##                   将两个相邻的标记(token)连接为一个单独的标记
#pragma       说明编译器信息

#warning       显示编译警告信息
#error          显示编译错误信息

预处理并不分析整个源代码文件, 它只是将源代码分割成一些标记(token), 识别语句中哪些是C语句, 哪些是预处理语句。

预处理器能够识别C标记, 文件名, 空白符, 文件结尾标志。

预处理过程如下:

1.头文件展开ps把#include的文件插入到相应位置

2.宏展开ps展开所有的宏,并删除#define

3.条件编译ps条件预编译指令比如:#if,#ifdef,#else

4.删除注释ps  // /**/的内容

5.添加行号和文件名标识

6.保留#pragrma命令ps指示编译器完成特定的动作

编译 : 编译过程就是把预处理完的文件进行一系列词法分析、语法分析、语义分析及优化后生产相应的汇编代码文件 , 编译器能够识别代码中的词汇、句子以及各种特定的格式,并将他们转换成计算机能够识别的二进制形式

编译也可以理解为“翻译”,类似于将中文翻译成英文、将英文翻译成象形文字,它是一个复杂的过程,大致包括词法分析、语法分析、语义分析、性能优化、生成可执行文件五个步骤,期间涉及到复杂的算法和硬件架构。

 汇编 : 汇编器(as)将hello.s翻译成机器语言指令,把这些指令打包成一种可重定位目标程序的格式,并将结果保存在目标文件hello.o中。hello.o文件是一个二进制文件,它的字节编码是机器语言指令而不是字符,如果我们在文本文件中打开hello.o文件,看到的将是一堆乱码。

链接 : C语言代码经过编译以后,并没有生成最终的可执行文件(.exe 文件),而是生成了一种叫做目标文件(Object File)的中间文件(或者说临时文件)。目标文件也是二进制形式的,它和可执行文件的格式是一样的。对于 Visual C++,目标文件的后缀是.obj;对于 GCC,目标文件的后缀是.o。链接(Link)其实就是一个“打包”的过程,它将所有二进制形式的目标文件和系统组件组合成一个可执行文件。完成链接的过程也需要一个特殊的软件,叫做链接器(Linker)。

 在C语言下:

在C++下

Windows下名字修饰规则 :

 

通过这里就理解了C语言没办法支持重载,因为同名函数没办法区分。而C++是通过函数修饰规则来区 分,只要参数不同,修饰出来的名字就不一样,就支持了重载 

 错误示例

void TestFunc(int a = 10) {
 cout<<"void TestFunc(int)"<<endl; }
void TestFunc(int a) {
 cout<<"void TestFunc(int)"<<endl; }
//这种类型就不可以进行函数重载
//因为他们的形参的类型是相同的

 C++中能否将一个函数按照C的风格来编译?

(1)C++中可以通过在函数声明前加 extern "C" 将一个函数按照 C 语言的风格来进行编译。

(2)C++语言支持函数重载。而C不支持函数重载。 

(3)函数在C中和C++中编译过的函数名字是不一样的。加上extern”C”是说明是说明C已经编译过的。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值