c++构造函数的重载,c语言函数重载是什么

  c++构造函数的重载,c语言函数重载是什么

  写在前面

  先说我的状态。五一是一个为期五天的假期。这几天都在玩,很少学习。我不后悔,也没必要。本来放假就是为了放松自己。我唯一要反思的是,别人在学,我自己心里想学,却学不会。这是我的缺点。我以后会克服的。试着尽快和你分享我的知识。今天,我和你们分享C和函数重载的关系。我们需要学习如何使用重载。

  函数重载我们可能对函数很熟悉,但是重载是什么意思呢?下面用一个具体的场景来分享一下。

  有一天,张三老板让你写一个两位数相加的函数。张三想,这不简单吗?动动手指,结果就出来了。很简单。

  int add(int x,int y)

  {

  返回x y;

  }

  现在老板一看张三的代码就怒不可遏。你怎么想呢?我想把12和10.9相加怎么办?这个只能加两个整数,回去修改!张三听到老板的话,忍不住反驳道:“这个我怎么改?我又不会写add1,add 2……”老板听到张三的嘟囔,生气地说:“你没学过函数重载吗?”看看下面的代码,回去好好学习,基础不扎实。

  张看到代码的时候很惊讶。C还能这么写吗?太好了,我想读一本好书。

  int add(int x,int y)

  {

  返回x y;

  }

  double add(double x,int y)

  {

  返回x y;

  }

  double add(int x,double y)

  {

  返回x y;

  }

  我们不希望这种事情发生在张三身上。我们先来看看函数重载的定义。

  函数重载:它是函数的特例。c允许在同一个作用域中声明几个具有相似函数的同名函数。这

  参数列表(参数的个数、类型或顺序)必须不同,常用于处理函数相似的不同数据类型的问题。

  可能你不喜欢这个定义,我给你总结一下。

  函数重载应满足以下要求。

  函数名相同参数的类型、个数、顺序不同。返回类型不需要函数重载的原则。一般我们知道可以应用函数重载,但是对于我们来说,需要看看它们的原理。为什么C语言不支持重载,而C支持?这些都是问题。

  为什么C可以支持重载?我们先用C编译器简单看一下如何执行程序。下面是我在Linux环境下用G做的事情。如果不是很了解,可以忽略,直接了解c的原理.

  我们先看现象,发现C能准确找到需要匹配的函数,这也是我们不解的地方。

  //test.h

  #杂注一次

  #包括iostream

  #包含stdio.h

  使用STD:cout;

  void func(int a,double b);

  void func(double a,int b);

  //test.cpp

  #包含“test.h”

  //写两个函数形成重载。

  void func(int a,double b)

  {

  printf(%d %lf ,a,b);

  }

  void func(double a,int b)

  {

  printf(%lf %d ,a,b);

  }

  //Mian.cpp

  #包含“test.h”

  int main()

  {

  func(10,2.20);

  返回0;

  }

  关于这一点,我们先简单说一下,之前已经详细讲过了。文件成为可执行程序需要以下四个步骤。

  宏替换头文件,展开注释,替换main.cpp-main.i test.cpp-test.i编译检查语法,代码转换成汇编语言main.i-main.s test.i-test.s汇编语言变成二进制语言,每个文件变成目标文件main.s-main.o test.s-test.o链接多个目标文件链接库。

  这里我们需要关注链接,这是我们一天中最重要的部分。

  链接只是目标文件的组合吗?不,它有很多任务要完成,其中最重要的是找到函数的地址,链接起来,合并在一起。

  当我们展开头文件时,Main.cpp中有func函数的声明和调用,在编译和汇编的过程中,有一个符号表,记录着函数的定义和对应的映射。这一点非常重要。符号表包含函数的名称和地址。

  每个目标文件(。o)包含一个符号表和一系列指令。我们来看看输入和完成函数的链接。

  现在是mian.o的指令,之前的一些指令都正常工作,直到遇到func这个点。如果你看过C语言的汇编语言,可能对下面这些比较熟悉。

  在func,编译器开始调用(func:),编译器不知道func的地址,但是func函数已经在头文件的扩展中声明了,所以编译器知道func是一个函数,所以先给它一个无效地址。当程序被链接时,编译器会看到这是一个无效的地址,并且会用other中的符号表来触碰函数名。o文件,遇到就填,找不到就报连接错误。

  可以理解为什么C在这里不支持重载。当我们接触函数名时,符号表中有很多相同的函数名,所以编译器不会识别使用哪一个。更何况,函数名相同的c文件有时无法编译。

  Gcc对函数名不做任何处理,这也是C语言不支持函数重载的原因。

  为什么C在这里可以支持函数重载?我们可以得到结果。由于无效函数在链接时会触及其他符号表中的函数名,所以我们只需要看看重载的函数名是否相同。你可能会困惑。重载的函数名不是一样的吗?是的,但是C编译器会做一些事情。这里的每个编译器都有自己的修改函数名的规则。这就是C支持重载的原理。

  这就是为什么C可以支持重载,G的函数修改后改成[_Z函数名长度函数名类型首字母1类型首字母2……]的原因,这也是为什么我们只要求参数列表,不要求返回值。

  用C语言互相调用。我们都知道C支持C语言的大部分语法。C和C语言可以互相调用吗?其实是有可能的。在一个大型程序中,有些部门可能用C写的函数,有些部门可能用C,如果不能互相使用,就要面对面。

  要创建一个静态库,我们可以把自己的代码编译成静态库或者动态库。这里我以一个静态库为例,看看如何在VS .

  调用C我们已经有了一个C语言的静态库,现在一个C项目需要使用这个静态库。我们如何使用它?它需要以下步骤。

  下面两张图都是修改环境的设置。我用的是VS2013,其他的应该差不多。请依次修改它们。

  这里我们可以调用C语言的静态库。让我们看看结果。

  #包含././heap/heap/heap . h //相对路径

  int main()

  {

  MyHeap myHeap

  InitMyHeap(我的堆);

  HeapPush( myHeap,1);

  HeapPush( myHeap,2);

  HeapPush( myHeap,3);

  显示(my heap);

  返回0;

  }

  为什么这是错的?我们不是已经建立了静态库吗?其实这种错误很容易分析。当C调用C语言中的函数时,C会自动修改函数名。当时C语言没有,所以不会遇到,链接会出错。

  extern“C”既然编译器不能自动识别C语言的函数名,难道就不能直接告诉编译器吗?Extern "c "就是这样一个函数。

  C工程中有时可能需要用C的风格编译一些函数,在函数前面加上extern“C”,意思是告诉编译器,

  按照C语言的规则编译函数。比如tcmalloc是google用C实现的项目,提供了tcmallc()和tcfree。

  两个接口来用,但是如果是C项目就不能用了,所以他用extern“C”来解决。

  Extern C //告知这是C语言中的函数声明

  {

  #包含././Heap/Heap/heap.h

  }

  int main()

  {

  MyHeap myHeap

  InitMyHeap(我的堆);

  HeapPush( myHeap,1);

  HeapPush( myHeap,2);

  HeapPush( myHeap,3);

  显示(my heap);

  返回0;

  }

  extern“C”的原理我们需要看看extern“C”的原理。使用extern“C”后,在编译C时,按照C语言的方法修改函数名,而不是变成C的规则,extern‘C’可以单独修改函数,也可以修改一系列函数,使用代码块。

  //test.h

  #杂注一次

  #包括iostream

  #包含stdio.h

  extern C void func(int a,double b);

  //test.cpp

  #包含“test.h”

  //写两个函数形成重载。

  void func(int a,double b)

  {

  printf(%d %lf ,a,b);

  }

  //Mian.cpp

  #包含“test.h”

  int main()

  {

  func(10,2.20);

  返回0;

  }

  C调用C,那么C能调用C吗?可以,但是也需要一些段落来完成。C语言如何识别C的规则?这是我们需要考虑的。

  我们把这个库变成了c语言的静态库。

  #包含././Heap/Heap/heap.h

  int main()

  {

  MyHeap myHeap

  InitMyHeap(我的堆);

  HeapPush( myHeap,1);

  HeapPush( myHeap,2);

  HeapPush( myHeap,3);

  显示(my heap);

  返回0;

  }

  不能让C语言的编译器识别C的函数名,那么能不能一编译完函数就把函数名写完?按照C语言来说,很简单。

  但即便如此,C语言还是会报错,因为头文件展开时,C语言根本不识别extern“C”,所以我们需要条件编译。

  条件编译修改静态库的方法如下,需要重新编译。

  //方法1

  #ifdef __cplusplus //C唯一

  # define EXTERNC extern C

  #否则

  #定义外部c

  #endif

  EXTERNC extern void InitMyHeap(my heap * pHeap);

  EXTERNC extern void heap push(my heap * pHeap,HP datatype x);

  EXTERNC extern bool is full(my heap * pHeap);

  EXTERNC extern bool IsEmpty(my heap * pHeap);

  EXTERNC extern int heap size(my heap * pHeap);

  EXTERNC extern void adjust down(my heap * pHeap);

  EXTERNC extern void adjustUp(my heap * pHeap);

  EXTERNC extern void显示(my heap * pHeap);

  EXTERNC extern HP datatype HeapTop(my heap * pHeap);

  EXTERNC extern void heap pop(my heap * pHeap);

  //方法2

  #ifdef __cplusplus

  外部 C

  {

  #endif

  extern void InitMyHeap(my heap * pHeap);

  extern void heap push(my heap * pHeap,HP datatype x);

  extern bool is full(my heap * pHeap);

  extern bool IsEmpty(my heap * pHeap);

  extern int heap size(my heap * pHeap);

  extern void adjust down(my heap * pHeap);

  extern void adjustUp(my heap * pHeap);

  extern void显示(my heap * pHeap);

  extern HP datatype HeapTop(my heap * pHeap);

  extern void heap pop(my heap * pHeap);

  #ifdef __cplusplus

  }

  #endif,就是这样。

  注意,这里有一点需要注意。当我们的C语言调用C静态库时,至少我们实际需要的那部分代码不能在extern‘C’修饰的函数中重载。

  C注本注以extern C 为主,部分远程内容需要注意。

  # #由extern c 修饰的函数与函数完全相同

  extern C 修饰的函数模块外有一个相同的函数,此编译器不会传递它。

  #ifdef __cplusplus

  外部 C

  {

  #endif

  void func(int a,int b)

  {

  printf(C : %d %d\n ,a,b);

  }

  #ifdef __cplusplus

  }

  #endif

  //完全一样。

  void func(int a,int b)

  {

  printf(C : %d %d\n ,a,b);

  }

  由extern“C”修改的函数和一个函数构成了重载。函数在由extern“C”修改的函数模块外部构成重载。这个编译器可以通过,但是extern C 修改的命名方法还是C语言的方式,重载是C .

  #包括iostream

  使用命名空间std

  #ifdef __cplusplus

  外部 C

  {

  #endif

  void func(int a,int b)

  {

  printf(C : %d %d\n ,a,b);

  }

  #ifdef __cplusplus

  }

  #endif

  void func(double a,int b)

  {

  printf(C : %lf %d\n ,a,b);

  }

  int main()

  {

  func(1,2);

  func(1.11,2);

  返回0;

  }

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

相关文章阅读

  • c语言调用退出函数 c语言退出整个程序怎么写
  • c语言中怎么给函数初始化 c语言的初始化语句
  • c语言编写函数计算平均值 c语言求平均函数
  • 详解c语言中的字符串数组是什么,详解c语言中的字符串数组结构,详解C语言中的字符串数组
  • 表达式求值c++实现,c语言实现表达式求值
  • 看懂c语言基本语法,C语言详解,C语言的基本语法详解
  • 用c语言实现快速排序算法,排序算法设计与实现快速排序C语言,C语言实现快速排序算法实例
  • 深入解析c语言中函数指针的定义与使用方法,深入解析c语言中函数指针的定义与使用情况,深入解析C语言中函数指针的定义与使用
  • 描述E-R图,E-R图举例,关于C语言中E-R图的详解
  • 折半查找法C语言,折半查找算法(算法设计题)
  • 折半查找法C语言,c语言折半法查找数据,C语言实现折半查找法(二分法)
  • 扫雷小游戏c++代码设计,c语言扫雷游戏源代码,C语言实现扫雷小游戏详细代码
  • 怎样统计程序代码行数,C语言统计行数,C#程序员统计自己的代码行数
  • 基于c语言的贪吃蛇游戏程序设计,用c语言编写贪吃蛇游戏程序,C语言实现简单的贪吃蛇游戏
  • 图的两种遍历算法,图的遍历算法代码c语言,Python算法之图的遍历
  • 留言与评论(共有 条评论)
       
    验证码: