🎁个人主页:我们的五年
🔍系列专栏:C++课程学习
🎉欢迎大家点赞👍评论📝收藏⭐文章
目录
🌈函数重载:
🍉1.参数个数不同:
🍉2.参数的类型不同:
🍉3.参数类型顺序不同:
🌈函数名修饰规则:
🌈链接:
前言:
本篇文章是上一篇文章C++入门(输入输出,缺省)其他C++入门知识。在这里感谢大家的支持,让我们一起进步。
🌈函数重载:
不同的话在不同的情况下会有不同的语义。函数也是一样的,有很多个名字一样的函数,但是在不同的情况下,调用的函数不同。
看一下函数重载的定义:
函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表( 参数个数 或 类型 或 类型顺序 )不同,常用来处理实现功能类似数据类型不同的问题。返回值类型不同是不构成函数重载的。(因为编译器无法区分)
同名函数的形参列表不同的三个方面:
下面三种情况,只要满足一种,就构成函数重载。
🍉1.参数个数不同:
看下面的代码:
#include<iostream>
using namespace std;
//形参的个数不同
//没有形参
void print()
{
cout << "print()" << endl;
}
//一个int形参
void print(int a)
{
cout <<"print(int a)" << endl;
}
//两个int形参
void print(int a,int b)
{
cout <<"print(int a,int b)"<<endl;
}
int main()
{
print();
print(10);
print(20,20);
}
🍉2.参数的类型不同:
下面print函数中:没有参数,只有一个int参数,只有一个double参数
#include<iostream>
using namespace std;
//形参的类型不同
void print()
{
cout << "print()" << endl;
}
//一个int形参
void print(int a)
{
cout << "print(int a)" << endl;
}
//一个double形参
void print(double a)
{
cout <<"print(double a)" << endl;
}
int main()
{
print();
print(10);
print(3.14);
}
🍉3.参数类型顺序不同:
#include<iostream>
using namespace std;
//形参的类型顺序不同
//顺序为int,char
void print(int a,char b)
{
cout << "int a,char b" << endl;
}
//顺序为char,int
void print(char a,int b)
{
cout << "char a,int b" << endl;
}
int main()
{
print(1, 'c');
print('c', 1);
}
那么这里就有一个问题:
为什么我们之前在学C语言的时候,我们没有学函数重载?
因为C语言是不支持函数重载的,C++是支持函数重载的。那问题又来了,为什么C语言不支持函数重载,C++支持函数重载?
这是因为C语言函数修饰只有函数名,只有函数名不同时才能区分。但是C++中,函数修饰要加上函数的形参,也就是说,名字一样的函数,当形参链表不同时,函数就是不同的,编译器就可以分辨出来。
不同的编译器,函数名修饰规则不同。
🌈函数名修饰规则:
当我们调用一个函数的时候,编译器是怎么去找这个函数的呢?
这里我们先来讲函数名修饰规则:
在C语言中函数的名称就是函数名,没有在这基础上加其他的信息。
但是在C++中,函数名的修饰还要加上其参数列表。
下面来看看linus下的C语言函数名的修饰和C++函数名的修饰:
1.C语言:
C语言编译完以后,就函数名称还是Add,和func,没有做其他的改变
2.C++:
Linux下,采用gcc编译,C++的修饰规则是【_z+函数长度+函数名+类型首字母】。(如果是指针的话,一级指针是p类型)
在C++中,我们可以很明显的发现,函数名除了Add以外还加了其他的东西,Add前面加了_z+函数名长度,在Add后面加了ii。然后我们看Add函数的参数,发现是两个int,然后我们是不是就可以推测,函数名是不是在后面还会加上参数的开头字母。
我们再来看看func函数,发现前面还是_z,func的长度为4,所以就是_z4。然后后面增加了idpi,i对应int,d对应double,pi对应int*。好像确实是没有什么问题的,所以C++中确实把函数形参也放在函数名里面,用以区分函数名相同,不同参数列表的函数(重载函数)。
vs上的修饰规则比较复杂,我们后面再来讲解。
🌈链接:
我们把代码写完,然后让编译器去翻译,然后执行就可以运行我们的代码。
我们调用一个函数,每个函数有不同的函数名,我们就可以通过符号表中寻找函数,找到函数的地址。正常情况下,我们会写很多个.c和.h文件,每个文件都会生成自己的目标文件。去找函数的地址就是发生在编译后链接前。
如果我们在a.c文件种使用了b.c文件中的Add函数,因为Add函数在a.c文件种没有定义,所以在a.c中是找不到的,在链接的时候,要去b.c文件的符号表中才能找到Add函数的地址,从而链表在一起。