淘宝站外网站可以做吗,一个网页大概多少钱,wordpress搭建个人博客,泰安网签查询2023君兮_的个人主页 即使走的再远#xff0c;也勿忘启程时的初心 C/C 游戏开发 Hello,米娜桑们#xff0c;这里是君兮_#xff0c;我之前看过一套书叫做《明朝那些事儿》#xff0c;把本来枯燥的历史讲的生动有趣。而C作为一门接近底层的语言#xff0c;无疑是抽象且难度颇… 君兮_的个人主页 即使走的再远也勿忘启程时的初心 C/C 游戏开发 Hello,米娜桑们这里是君兮_我之前看过一套书叫做《明朝那些事儿》把本来枯燥的历史讲的生动有趣。而C作为一门接近底层的语言无疑是抽象且难度颇深的。我希望能努力把抽象繁多的知识讲的生动又通俗易懂因此咱们这个讲解C的系列博客就叫做《C那些事儿》啦而今天我们要讲的内容是C中的函数重载与引用 好了废话不多说开始我们今天的学习吧 C那些事儿 函数重载函数重载的概念C支持函数重载的原理--名字修饰(name Mangling) 引用1.引用概念2.引用特性3.常引用4.引用的使用场景(1).做函数的参数(2).做返回值 传值与传引用效率比较引用和指针的区别 总结
函数重载
说到函数重载很多人不理解重载是什么意思其实它就在我们身边我来举个例子 一天你的舍友有节课没去上课但是碰巧老师上课点名点到他了老师就问你他来了吗 你回答说如来 老师又问你到底来没来 你回答说如来 于是老师就把你请出教室了 自然语言中一个词可以有多重含义人们可以通过上下文来判断该词真实的含义即该词被重载了那在C中什么是函数重载呢
函数重载的概念
函数重载是函数的一种特殊情况C允许在同一作用域中声明几个功能类似的同名函数这 些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同常用来处理实现功能类似数据类型 不同的问题
#includeiostream
using namespace std;// 1、参数类型不同
int Add(int x, int y)
{cout int类型的Add x y endl;return x y;
}
double Add(double x, double y)
{cout double类型的Add x y endl;return x y;
}
// 2、参数个数不同
void f()
{cout f() endl;
}
void f(int a)
{cout f(int a) endl;
}
// 3、参数类型顺序不同
void f(int a, char b)
{cout f(int a,char b) endl;
}
void f(char b, int a)
{cout f(char b, int a) endl;
}int main()
{int x 0;int y 0;Add(1, 5);f();f(10);f(10, b);f(a, 10);return 0;
}了解了函数重载的概念和基本使用方法后很多人可能会想为什么C支持函数重载而C不支持函数重载呢下面我们来讨论一下这个问题
C支持函数重载的原理–名字修饰(name Mangling)
在C/C中一个程序要运行起来需要经历以下几个阶段预处理、编译、汇编、链接。 这里对于没有接触过汇编语言以及编译链接的同学来说非常复杂也不是我几句话就能说清楚的因此大家简单理解记住结论即可我也不会讲太深随着之后我们C之旅的进程当我们接触到更多有关内容后我再在合适的地方具体解释。 这张图片大概展示了在编译链接阶段各阶段进行的操作由于Windows下vs的修饰规则过于复杂而Linux下g的修饰规则简单易懂我们通过在linux下编译后生成的汇编来讲解这部分内容 Linux环境下采用C语言编译器编译后结果 结论在linux下采用gcc编译完成后函数名字的修饰没有发生改变 采用C编译器编译后结果 结论在linux下采用g编译完成后函数名字的修饰发生改变编译器将函数参数类型信息添加到修改后的名字中 最终结论在目前学习阶段记住这个结论就行 1.C语言之所以没办法支持重载是因为同名函数没办法区分。而C是通过函数修饰规则来区分只要参数不同修饰出来的名字就不一样就支持了重载。 2. 如果两个函数函数名和参数是一样的返回值不同是不构成重载的因为调用时编译器没办法区分。 引用
1.引用概念
引用不是新定义一个变量而是给已存在变量取了一个别名编译器不会为引用变量开辟内存空间它和它引用的变量共用同一块内存空间在C中引用的作用类似于指针但是它不开辟空间在很多情况下引用是比使用指针更好的选择。至于起别名引用就相当于这个变量的外号一样 比如 孙悟空如果你是唐僧你可以叫他悟空 如果你是猪八戒或者沙僧你可以叫他大师兄 如果你是某地界的土地神你可以叫他孙大圣 如果你是他的死对头你可以叫他泼猴或者弼马温…上述的这些都是孙悟空的引用:也就是别名 类型 引用变量名(对象名) 引用实体
void Test()
{int a 10;int ra a;//定义引用类型printf(%p\n, a);printf(%p\n, ra);
}int main()
{Test();
}引用与原变量指向同一块空间 注意引用类型必须和引用实体是同种类型的
2.引用特性
1. 引用在定义时必须初始化2. 一个变量可以有多个引用3. 引用一旦引用一个实体再不能引用其他实体
void Test()
{int a 10;int ra a;//定义引用类型int b a;//一个变量可以有多个别名printf(%p\n, a);printf(%p\n, ra);printf(%p\n, b);
}多个引用仍然指向同一块空间 必须初始化不然会报错
3.常引用
void TestConstRef()
{
const int a 10;
//int ra a; // 该语句编译时会出错a为常量
const int ra a;
}最常见的一种常引用我们知道引用作为变量的别名当改变引用的值时是会改变变量的值的因此当变量被const修饰时它的引用也必须用const修饰
void TestConstRef()
{// int b 10; // 该语句编译时会出错b为常量
const int b 10;
double d 12.34;
//int rd d; // 该语句编译时会出错类型不同
const int rd d;
}当我们直接吧一个常量给一个引用时必须加const原因与第一种情况相同而常量就更不可能让你通过引用来修改它的值了
void TestConstRef()
{
double d 12.34;
//int rd d; // 该语句编译时会出错类型不同
const int rd d;
}这里是存在一个类型的隐式转换的把double类型的转换成int型这里类型发生了转换因此我们也不能通过别名来修改变量因此必须加const
4.引用的使用场景
(1).做函数的参数
void Swap(int left, int right)
{
int temp left;
left right;
right temp;
}和指针在这里的使用方法是类似的就不过多展开了
(2).做返回值
int Count()
{
static int n 0;
n;
// ...
return n;
}注意如果函数返回时出了函数作用域如果返回对象还在(还没还给系统)则可以使用引用返回如果已经还给系统了则必须使用传值返回。
下面我们来看一个例子
int Add(int a, int b)
{
int c a b;
return c;
}
int main()
{
int ret Add(1, 2);
Add(3, 4);
cout Add(1, 2) is : ret endl;
return 0;
} 因此当我们运行时出现这种结果也就不奇怪了 那应该怎么解决上述的这种问题呢很简单我们让函数解释时不会释放申请的空间就好了
int Add(int a, int b)
{static int c a b;return c;
}
int main()
{int ret Add(1, 2);Add(3, 4);cout Add(1, 2) is : ret endl;return 0;
} 传值与传引用效率比较
以值作为参数或者返回值类型在传参和返回期间函数不会直接传递实参或者将变量本身直接返回而是传递实参或者返回变量的一份临时的拷贝因此用值作为参数或者返回值类型效率是非常低下的尤其是当参数或者返回值类型非常大时效率就更低。总的来说你在这里可以暂时把引用类比成指针来使用等之后学习了类和对象之后才能更加明白引用在使用时候的妙处
引用和指针的区别
在语法概念上引用就是一个别名没有独立空间和其引用实体共用同一块空间。在底层实现上实际是有空间的因为引用是按照指针方式来实现的。
int main()
{//int ret Add(1, 2);char c a;char rc c;char* rrc c;cout rc sizeof(c) endl;cout rrc sizeof(rrc) endl;return 0;
} 在这里编译器告诉我们引用占一个字节而指针占8个字节可事实真的如此吗 通过底层的汇编代码我们可以知道实际上引用是按指针方式实现的是占空间的至于为什么编译器告诉你它不占空间因为在C规定时说引用是一个别名是不占空间的它总不能自己打自己脸呀 引用与指针的其他区别点 1. 引用概念上定义一个变量的别名指针存储一个变量地址。 2. 引用在定义时必须初始化指针没有要求 3. 引用在初始化时引用一个实体后就不能再引用其他实体而指针可以在任何时候指向任何 一个同类型实体 4. 没有NULL引用但有NULL指针 5. 在sizeof中含义不同引用结果为引用类型的大小但指针始终是地址空间所占字节个数(32 位平台下占4个字节) 6. 引用自加即引用的实体增加1指针自加即指针向后偏移一个类型的大小 7. 有多级指针但是没有多级引用 8. 访问实体方式不同指针需要显式解引用引用编译器自己处理 9. 引用比指针使用起来相对更安全 总结 好啦我们今天的内容就先到这里啦今天讲解了函数重载与引用使用方法以及有关它们使用的细节和注意事项这两块的知识点会一直伴随你C学习之路是非常重要的因此希望大家把有关的重点和难点多看几遍加深理解。 有任何的问题和对文章内容的疑惑欢迎在评论区中提出当然也可以私信我我会在第一时间回复的 新人博主创作不易如果感觉文章内容对你有所帮助的话不妨三连一下再走呗。你们的支持就是我更新的动力 **可莉请求你们三连支持一下博主点击下方评论点赞收藏帮帮可莉吧**