网站开发职业技能简历,淄博网站制作定制视觉,网站seo检测报告,百度快速收录提交工具好的#xff0c;我们继续#xff0c;这是 C专栏的第二篇博客#xff0c;还没读过上一篇博客可以进入我创建的专栏阅读
入门C#xff08;上#xff09;再回来哦~ 下面我们要讲的第一个概念就是函数重载
函数重载 1. 函数重载概念
什么是函数重载#xff1f; 简单来说…好的我们继续这是 C专栏的第二篇博客还没读过上一篇博客可以进入我创建的专栏阅读
入门C上再回来哦~ 下面我们要讲的第一个概念就是函数重载
函数重载 1. 函数重载概念
什么是函数重载 简单来说函数重载就是一词多义 下面给出它的详细定义 函数重载是函数的一种特殊情况C允许在同一作用域中声明几个功能类似的同名函数这些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同常用来处理实现功能类似数据类型不同的问题 注意不同作用域可以随便同名 同一作用域要同名则需要满足重载的规则 下面我们来看一下几个构成函数重载的例子 1.参数个数不同 2.参数类型不同 3.参数类型顺序不同 然后我们再来看一下下面的代码 为什么这里会报错
可以肯定的是这是不需要重载关系也是ok的因为不同作用域可以随便同名 但是在这里发生了调用歧义 所以才会报错~ 再看一个例子 这里的函数虽然构成重载但是它们的调用会有歧义 我们再看一个例子 这里我们可以得出返回值不同是无法构成重载的
因为返回值不同无法区分所以返回值不是重载的条件 综上所属调用里面中有歧义的都是不行的 最后关于函数的重载我们需要记住它一定是和形参的类型是有关系的
还有就是将调用歧义和函数重载 区分开来 2.C支持函数重载的原理
所以为什么C支持函数重载而C语言不支持函数重载呢
在这里简单介绍一下
对于C语言不支持函数重载我们是可以很好理解的这与之前我们在C语言中讲过的编译链接过程有关 一个程序要运行起来需要经历以下几个阶段预处理、编译、汇编、链接
链接时
1.C语言是直接用函数名字去查找函数的地址的所以不支持函数重载
2.在C中是用修饰后的函数名字去查找的只要参数不同修饰出来的名字就不一样所以就支持函数重载
但是在如果我们在调用时不指定返回值类型那么我们并不知道调函数的哪个返回值就是调用时有了歧义无法区分
所以对于C的函数重载而言函数返回值不同并不能构成函数重载因为这不是函数名修饰规则
这也印证了我们在之前说的函数重载与 参数个数 或 类型 或 类型顺序 三者有关 接下来我们来看一下引用
引用 1. 引用概念
引用不是新定义一个变量而是给已存在变量取了一个别名编译器不会为引用变量开辟内存空 间它和它引用的变量共用同一块内存空间 引用的形式 类型 引用变量名 引用实体 举个例子 注意引用类型必须和引用实体是同种类型的
2. 引用特性 1.引用在定义时必须初始化 2.一个变量可以有多个引用 3. 引用一旦引用一个实体再不能引用其他实体 对于第一个特性其实很好理解我们看下面的这行代码
int a; // 该条语句编译时会出错 对于这里的第二个特性可以看下面的代码 我们发现这里的abcd都是同一个东西 然后是第三个特性我们看下面的代码
int main()
{int x 0;int y x;int z 1;y z;return 0;
}
这里是 y变成z的别名呢 还是z赋值给y
根据引用的第三个特性引用一旦引用一个实体再不能引用其他实体
所以这里的代码y z 意思是将 z赋值给y
我们可以验证一下 3. 常引用 我们来看一下下面的代码 const int a 10;int ra a;
该语句编译时会出错,
因为a经过const修饰后是只读的 而ra变成a的别名ra的权限是可读可写的
这是一种权限的放大即原来 只是可读的变成的 可读可写的 所以不可以
总之这里我们需要知道权限不能放大 再看下面的代码 const int* p1 m;
int* p2 p1;该语句编译时也会出错这也是权限的放大 因为 const修饰是的*p1 所以 p1可以修改 *p1不可以
而int* p2 p1 如果我们改变*p2那么*p1就也会被修改所以不可以
对应的我们可以将 int* p2 p1 修改为 const int p2 p1 这样就是权限的平移是可以的 再看一个代码 int* p1 x;const int* p2 p1;
这是可以的
p1是可读可写的p2只可读
这是一种权限的缩小即原来可读可写的变成了只可读 所以可以
这里我们可以知道权限可以缩小 看下面代码
double d 12.34;
int rd d; int rd d; 该语句编译时会出错这是为什么呢仅仅因为类型不同吗
可是如果我换成 const int rd d 就不会报错这又是为什么呢
这里其实会进行一个类型的转换而类型转换又会生成临时变量
知道了这点我们就可以分析其中的原因了int rd d 这里要将d给rd这里是要类型转换的而类型转换又需要临时变量所以其实rd引用的不是d而是那个临时变量
我们还知道临时变量具有常性相当与const修饰所以这里的int rd d存在权限的放大
而我们将nt rd d 改成 const int rd d 就不会是权限的放大而是权限的平移所以可以 总结一下权限可以缩小可以平移但绝不可以放大 4.使用场景
做参数
void Swap(int left, int right)
{int temp left;left right;right temp;
}
这里我们用引用的话就不用像C语言那样去传指针了就会变得更加的方便~ 而关于做返回值的使用场景我们暂且不讲留到以后讲类和对象时再说~ 5. 传值、传引用效率比较 下面我们用一段代码看一下传值和传引用效率上的区别
#include time.h
struct A{ int a[10000]; };void TestFunc1(A a){}
void TestFunc2(A a){}void TestRefAndValue()
{
A a;
// 以值作为函数参数
size_t begin1 clock();
for (size_t i 0; i 10000; i)
TestFunc1(a);
size_t end1 clock();
// 以引用作为函数参数
size_t begin2 clock();
for (size_t i 0; i 10000; i)
TestFunc2(a);
size_t end2 clock();
// 分别计算两个函数运行结束后的时间
cout TestFunc1(A)-time: end1 - begin1 endl;
cout TestFunc2(A)-time: end2 - begin2 endl;
} Tips第二个函数运行的时间为0是取整后的结果表示运行时间不超过1ms 通过上述代码的比较我们由此发现传值和指针在作为传参上效率相差很大
我们也能感知到引用传参的一个极大的好处 6.引用和指针的区别
讲到这里引用的知识差不多就介绍完了最后我们来简单的对比一下
引用和指针的不同点:
1. 在语法上我们认为引用定义一个变量的别名指针存储一个变量地址
所以在语法层面上我们认为引用不开空间比如int b a;而指针是要开空间的
比如 int * p a; 但是在底层其实它们是一样的都是指针
2. 引用在定义时必须初始化指针没有要求
3. 引用在初始化时引用一个实体后就不能再引用其他实体而指针可以在任何时候指向任何 一个同类型实体
4. 没有NULL引用但有NULL指针但这个也不是绝对的比如说 int* ptr NULL; int r *ptr; 这里看起来对空指针解引用但是不会报错因为在底层其实只是存ptr的地址没有解引用不过如果我们接下来要访问 cout rendl; 才会解引用
5. 在sizeof中含义不同引用结果为引用类型的大小但指针始终是地址空间所占字节个数(32 位平台下占4个字节64位平台下占8个字节)
比如我们看下面的代码及运行结果 6. 引用自加即引用的实体增加1指针自加即指针向后偏移一个类型的大小
7. 有多级指针但是没有多级引用
8. 访问实体方式不同指针需要显式解引用引用 是编译器自己处理因为引用底层也是指针但是它解引用不需要显式处理
9. 引用比指针使用起来相对更安全所以在C我们更倾向用引用 结语 好啦这篇C入门中篇的博客就先写到这里吧 我们介绍了C语言没有的两个新的概念函数重载和引用希望大家能有所收获~ 如果文中分析题解代码有不足的地方欢迎大家在评论区讨论和指正 接下来我也会持续更新与C相关内容的博客 让我们在接下来的时间里一起学习一起进步吧~