搜索优化公司,西安快速排名优化,WordPress命令执行漏洞,杭州职业能力建设网欢迎来CILMY23的博客
本篇主题为 掌握C函数重载和引用开启代码优化的新篇章
个人主页#xff1a;CILMY23-CSDN博客
个人专栏#xff1a; | | | CILMY23-CSDN博客
上一篇博客#xff1a;第一个C结构#xff0c;C关键字#xff0c;命名空间#xff0c;C的输入输出函数重载和引用开启代码优化的新篇章
个人主页CILMY23-CSDN博客
个人专栏 | | | CILMY23-CSDN博客
上一篇博客第一个C结构C关键字命名空间C的输入输出缺省参数
感谢观看支持的可以给个一键三连点赞关注收藏。 目录 一、 函数重载
1.1 函数重载的概念
1.2 cpp是如何支持重载的呢
1.3 Linux -- gcc 编译器下的规则
1.4 Visual Studio 2019 的命名规则
二、 引用
2.1 引用概念
2.2 引用的用法
2.3 引用的特点
2.4 引用的应用1 --- 做参数 2.5 引用不能代替指针的原因
2.6 引用的应用2 --- 做返回值
2.7 引用和指针的区别
2.8 引用和指针的不同 本文前言 上一篇简要介绍了C编程语言的初级概念。我们学习了C的程序结构和基本语法了解了关键字的作用和用法。通过命名空间我们可以避免命名冲突并组织代码。使用cin和cout进行输入输出操作方便与用户交互。缺省参数可以使函数调用更灵活。通过学习我们打下了C编程的基础。接下来我们将继续学习重点知识 --- 函数重载 一、 函数重载
在过去我们学习C语言的时候通常都会碰到一个问题我们定义函数的时候是不让同名的也就是ADD函数只有一个所以我们为了方便起见通常用一个宏来定义一个type这样方便修改函数的数据类型而在C中我们引入了函数重载的概念它允许函数同名但要求参数不同
1.1 函数重载的概念
函数重载是函数的一种特殊情况C允许在同一作用域中声明几个功能类似的同名函数这些同名函数的形参列表(参数个数或类型或类型顺序)不同常用来处理实现功能类似数据类型不同的问题 函数重载一共有三种方式
1.函数参数的数据类型不同
2.函数参数的顺序不同
3.函数参数的个数不同 //函数重载
//1.函数参数的数据类型不同
int Add(int a, int b)
{cout this is int Add endl;return a b;
}double Add(double a, double b)
{cout this is double Add endl;return a b;
}
//2.函数参数的顺序不同
void A(int a, char b)
{cout void A(int a, char b) endl;
}void A(char b, int a)
{cout void A(char b, int a) endl;
}
//3.函数参数的个数不同
void f()
{cout void f() endl;
}void f(int a)
{cout void f(int a) endl;
} 注意函数重载不能依靠返回值的不同来构成重载因为调用时无法根据参数列表确定调用哪个重载函数
例如double Add() 和int Add()不能构成重载函数。
1.2 cpp是如何支持重载的呢
在C语言中我们的C是直接通过函数名去找地址的所以它不支持重载的原因是同名函数不知道该找谁的地址。
那我们知道从编译到可执行程序需要经历四个阶段预编译编译汇编链接第一个C结构C关键字命名空间C的输入输出缺省参数
那C是如何支持的呢我们引入了一个规则 --- 函数名修饰规则, 我们不是要通过函数名来查找函数地址吗那如果函数名的修饰再加上参数以及其他的一些符号这样通过不同函数名和不同的参数就能确定一个唯一的地址。
但是并没有很强制的规定所以各个编译器都自己实现了一套命名规则。
1.3 Linux -- gcc 编译器下的规则
在gcc当中它们的命名方式比较简约。 _Z 函数名称长度 函数名称 参数类型首字母 1.4 Visual Studio 2019 的命名规则
当我们声明和定义分离的时候把定义部分去掉就可以在Visual 的窗口中看到报错
当我们写很多种的函数就可以总结一个规律
visual 的修饰 函数名称 YA 参数类型 Z 二、 引用
2.1 引用概念
引用不是新定义一个变量而是给已存在变量取了一个别名编译器不会为引用变量开辟内存空 间它和它引用的变量共用同一块内存空间。
2.2 引用的用法
引用的语法如下 类型 对象名 引用实体 例如 //引用int main()
{int a 0;int b a;int c b;cout b endl;a;cout b endl;b;cout c endl;} 结果输出012
b 就是 a 别名是可以无限取的就跟人的名字一样有无数外号别名也可以有别名。
注意引用类型必须和引用实体是同种类型的
2.3 引用的特点
1. 引用在定义时必须初始化 2. 一个变量可以有多个引用 3. 引用一旦引用一个实体再不能引用其他实体
错误1 int a 10;
int ref; // 无法通过编译因为ref没有进行初始化错误2 int a 10;
int b 20;
int ref a; // ref现在引用a
int rref a;
2.4 引用的应用1 --- 做参数
过去我们在C语言中要交换两个变量的值通常用函数指针额外变量来进行交换现在我们可以用引用来处理。 //引用特点 --- 做函数参数
void Swap(int* a, int* b)
{int tmp *a;*a *b;*b tmp;
}void Swap(int a, int b)
{int tmp a;a b;b tmp;
}int main()
{int n1 10;int n2 20;Swap(n1, n2);
} Swap函数使用的是引用参数对a和b的操作会直接影响到n1n2不需要额外开辟空间。
参数也分两种a.输出型参数b.是对象比较大减少拷贝提高效率 2.5 引用不能代替指针的原因 指针和引用的功能有部分是类似的有些复杂场景是可以替代的但是不能完全替代指针。 引用不能完全替代指针的原因引用定义后不能改变指向
2.6 引用的应用2 --- 做返回值 我们在调用函数的时候出了函数作用域的东西就可能会出现随机值 int fun1()
{int a 0;return a;
}int main()
{int ret fun1();return 0;
} 传值返回的函数ret就是读取不到a函数会临时拷贝a的值存在寄存器中然后将a的值返回。
但函数也可以传引用像以下情况就不行 int fun1()
{int a 0;return a;
}int main()
{int ret fun1();cout ret endl;return 0;
} 但是这里会报错这里栈帧没清所以值是0也因此值在不同平台是不同的
如果函数返回时出了函数作用域如果返回对象还在(还没还给系统)则可以使用引用返回例如全局变量静态变量堆上变量等如果已经还给系统了例如局部变量则必须使用传值返回。
2.7 引用和指针的区别 在语法概念上引用就是一个别名没有独立空间和其引用实体共用同一块空间。在底层实现上实际是有空间的因为引用是按照指针方式来实现的。 int main()
{int a 10;int ra a;ra 20;int* pa a;*pa 20;return 0;
} 汇编代码的对比
引用和指针的效率对比 #include time.h
struct A { int a[10000]; };
A a;
// 值返回
A TestFunc1() { return a; }
// 引用返回
A TestFunc2() { return a; }
void TestReturnByRefOrValue()
{// 以值作为函数的返回值类型size_t begin1 clock();for (size_t i 0; i 100000; i)TestFunc1();size_t end1 clock();// 以引用作为函数的返回值类型size_t begin2 clock();for (size_t i 0; i 100000; i)TestFunc2();size_t end2 clock();// 计算两个函数运算完成之后的时间cout TestFunc1 time: end1 - begin1 endl; cout TestFunc2 time: end2 - begin2 endl;
} 结果如下
2.8 引用和指针的不同 1.引用概念上定义一个变量的别名指针存储一个变量地址。 2.引用在定义时必须初始化指针没有要求 3.引用在初始化时引用一个实体后就不能再引用其他实体而指针可以在任何时候指向任何 个同类型实体 4.没有NULL引用但有NULL指针 5.在sizeof中含义不同:引用结果为引用类型的大小但指针始终是地址空间所占字节个数(32位平台下占4个字节) 6.引用自加即引用的实体增加1指针自加即指针向后偏移一个类型的大小 7.有多级指针但是没有多级引用 8.访问实体方式不同指针需要显式解引用引用编译器自己处理 9.引用比指针使用起来相对更安全 感谢各位同伴的支持本期C入门篇就讲解到这啦如果你觉得写的不错的话可以给个一键三连点赞关注收藏若有不足欢迎各位在评论区讨论。