C++语言学习(二)——⭐缺省参数、函数重载、引用

1.⭐缺省参数

(1)缺省参数概念

缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。

void Func(int a = 0)
{cout<<a<<endl;
}
int main()
{Func();     // 没有传参时,使用参数的默认值Func(10);   // 传参时,使用指定的实参return 0;
}

(2)缺省参数分类

①全缺省参数

void Func(int a = 10, int b = 20, int c = 30)
{cout<<"a = "<<a<<endl;cout<<"b = "<<b<<endl;cout<<"c = "<<c<<endl;
}

②半缺省参数

void Func(int a, int b = 10, int c = 20)
{cout<<"a = "<<a<<endl;cout<<"b = "<<b<<endl;cout<<"c = "<<c<<endl;
}

1. 半缺省参数必须从右往左依次来给出,不能间隔着给

2. 缺省参数不能在函数声明和定义中同时出现如果生命与定义位置同时出现,恰巧两个位置提供的值不同,那编译器就无法确定到底该 用那个缺省值。

3. 缺省值必须是常量或者全局变量

4. C语言不支持(编译器不支持)

2. ⭐函数重载

(1)函数重载概念

函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数或类型或类型顺序)不同,常用来处理实现功能类似数据类型不同的问题。

三种形式:

  • 参数类型不同
  • 参数个数不同
  • 参数类型顺序不同
#include<iostream>
using namespace std;
// 1、参数类型不同
int Add(int left, int right)
{cout << "int Add(int left, int right)" << endl;return left + right;
}
double Add(double left, double right)
{cout << "double Add(double left, double right)" << endl;return left + right;
}// 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()
{Add(10, 20);Add(10.1, 20.2);f();f(10);f(10, 'a');f('a', 10);return 0;
}

(2)为什么C++支持函数重载,而C语言不支持呢?

在C/C++中,一个程序要运行起来,要经历以下几个阶段:预处理、编译、汇编、链接

  1. 项目通常是由多个头文件和多个源文件构成,【当前a.cpp中调用了b.cpp中定义的Add函数时】,编译后链接前,a.o的目标 文件中没有Add的函数地址,因为Add是在b.cpp中定义的,所以Add的地址在b.o中。
  2. 所以链接阶段就是专门处理这种问题,链接器看到a.o调用Add,但是没有Add的地址,就 会到b.o的符号表中找Add的地址,然后链接到一起。
  3. 那么链接时,面对Add函数,链接接器会使用哪个名字去找呢?这里每个编译器都有自己的函数名修饰规则。
  4. 在linux下,采用g++编译完成后,函数名字的修饰发生改变,编译器将函数参数类型信息添加到修改后的名字中。
  5. 通过这里就理解了C语言没办法支持重载,因为同名函数没办法区分。而C++是通过函数修饰规则来区分,只要参数不同,修饰出来的名字就不一样,就支持了重载。
  6. 如果两个函数函数名和参数是一样的,返回值不同是不构成重载的,因为调用时编译器没办法区分。

3. ⭐引用

(1)引用概念

引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。

类型& 引用变量名(对象名) = 引用实体;

注意:引用类型必须和引用实体是同种类型的

void TestRef()
{int a = 10;int& ra = a;//<====定义引用类型printf("%p\n", &a);printf("%p\n", &ra);
}

(2)引用特性

  1. 引用在定义时必须初始化
  2. 一个变量可以有多个引用
  3. 引用一旦引用一个实体,再不能引用其他实体
void TestRef()
{int a = 10;// int& ra;   // 该条语句编译时会出错int& ra = a;int& rra = a;printf("%p %p %p\n", &a, &ra, &rra);  
}

(3)常引用

常引用是指使用 const 关键字修饰的引用。常引用用于指示在函数中不会修改引用所绑定的对象。这样做的好处是可以确保在函数内部不会意外地修改传递给函数的参数,同时还能够允许函数接受常量作为参数。

void TestConstRef()
{const int a = 10;//int& ra = a;   // 该语句编译时会出错,a为常量const int& ra = a;// int& b = 10; // 该语句编译时会出错,b为常量const int& b = 10;double d = 12.34;//int& rd = d; // 该语句编译时会出错,类型不同const int& rd = d;
}

(4)使用场景

①做参数

void Swap(int& left, int& right)
{int temp = left;left = right;right = temp;
}

②做返回值

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);cout << "ret is :" << ret << endl;Add(3, 4);cout << "ret is :" << ret << endl;return 0;
}

(5)传值、传引用效率比较

以值作为参数或者返回值类型,在传参和返回期间,函数不会直接传递实参或者将变量本身直接返回,而是传递实参或者返回变量的一份临时的拷贝,因此用值作为参数或者返回值类型,效率是非常低下的,尤其是当参数或者返回值类型非常大时,效率就更低。

#include <time.h>
struct A { int a[10000]; };
void TestFunc1(A a) {}
void TestFunc2(A& a) {}
void main()
{A a; // 创建一个结构体A的实例a// 1.以值作为函数参数的情况size_t begin1 = clock(); // 获取执行函数调用前的时间for (size_t i = 0; i < 10000; ++i) // 传值调用10000次,这种情况每调用一次就会产生一次拷贝TestFunc1(a);size_t end1 = clock();// 获取执行函数调用结束的时间// 2.以引用作为函数参数size_t begin2 = clock();// 获取执行函数调用前的时间for (size_t i = 0; i < 10000; ++i) // 传引用调用10000次,这种情况每次调用都直接用的引用TestFunc2(a);size_t end2 = clock();// 获取执行函数调用结束的时间// 分别计算两个函数运行结束后的时间cout << "TestFunc1(A)-time:" << end1 - begin1 << endl;cout << "TestFunc2(A&)-time:" << end2 - begin2 << endl;// 结果// TestFuncl(A) - time:9// TestFunc2(A&) - time : 0
}

(6)引用和指针的区别

语法:

  1. 引用是别名,语法上不开空间,指针是地址,需要开空间存地址
  2. 引用必须初始化,指针可以初始化也可以不初始化
  3. 引用不能改变指向,指针可以
  4. 引用相对更安全,没有空引用,但有空指针,容易出现野指针,但是不容易出现野引用
  5. sizeof、++、解引用访问等方面的区别

底层:

  • 汇编层面上,没有引用,都是指针,引用在编译后也转换成指针了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/595774.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用Docker部署SpringBoot项目(避坑+超级详细版本,Linux运维基础72问

使用Docker部署SpringBoot项目&#xff08;避坑超级详细版本&#xff09; 所有文章不设限&#xff0c;我们相遇偶然&#xff0c;相散坦然&#xff0c;互不打扰&#xff0c;各自安好&#xff0c;向阳而生 首先呢&#xff0c;非常感谢我们一起相遇在这个地方&#xff0c;想必此…

浅析入侵检测系统及最新研究

1. 入侵检测系统 IDS&#xff1a;入侵检测系统&#xff08;Intrusion Detection System&#xff09;是一种被动监控方式&#xff0c;用于检测一个团体或者个人的网络安全威胁。如果检测到潜在的网络入侵&#xff0c;入侵检测系统会生成警报&#xff0c;通知安全人员或者采取相…

大型语言模型(LLMs)面试常见问题解析

概述 这篇文章[1]是关于大型语言模型&#xff08;LLMs&#xff09;的面试问题和答案&#xff0c;旨在帮助读者准备相关职位的面试。 token&#xff1f; 在大型语言模型中&#xff0c;token 指的是什么&#xff1f; 分词&#xff08;Tokenization&#xff09;&#xff1a;可以将…

好物视频素材哪里找?8个视频素材库免费网址大全

在这个数字化的时代&#xff0c;高清视频已经成为了一种强大的沟通工具&#xff0c;无论是个人分享、教育培训还是商业广告&#xff0c;高质量的视频内容都能够有效地吸引观众的注意力。为了帮助你轻松找到理想的无水印视频素材&#xff0c;下面我为你精心挑选了一系列全球视频…

八股面试速成—计算机网络部分

暑期实习面试在即&#xff0c;这几天八股和算法轮扁我>_ 八股部分打算先找学习视屏跟着画下思维导图&#xff0c;然后看详细的面试知识点&#xff0c;最后刷题 其中导图包含的是常考的题&#xff0c;按照思维导图形式整理&#xff0c;会在复盘后更新 细节研究侧重补全&a…

注解式 WebSocket - 构建 群聊、单聊 系统

目录 前言 注解式 WebSocket 构建聊天系统 群聊系统&#xff08;基本框架&#xff09; 群聊系统&#xff08;添加昵称&#xff09; 单聊系统 前言 很久之前&#xff0c;咱们聊过 WebSocket 编程式的写法&#xff0c;但是有些过于繁琐&#xff0c;这次来看看更接近现代的注…

FaaF:利用事实作为评估RAG的函数方法

原文地址&#xff1a;faaf-facts-as-a-function-for-evaluating-rag 2024 年 4 月 5 日 在某些情况下&#xff0c;我们使用其他语言模型来验证RAG的输出结果&#xff0c;但这种方法并未能有效识别出数据生成过程中的错误和缺失。 论文解析 挑战 评估的可靠性和效率&#xff…

Note-模型的特征学习过程分析

模型的学习过程 将数据的特征分为,有用特征和无用特征(噪声).有用特征与任务有关,无用特征与任务无关. 模型的学习过程就是增大有用特征的权重并减少无用特征的权重的过程. 神经网络反向传播过程简化如下: y a 0 x 0 a 1 x 1 , l o s s 0.5 ∗ ( y l a b e l − y ) 2 y …

出门一笑, “栈” 落江横 (Java篇)

本篇会加入个人的所谓‘鱼式疯言’ ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人…

C语言中strcpy函数的实现

C语言中strcpy函数的实现 为了便于和strcpy函数区别&#xff0c;以下命令为_strcpy。 描述&#xff1a;实现strcpy&#xff0c;字符串拷贝函数&#xff0c;函数原型如下&#xff1a; char* strcpy(char* _Destination, const char *_Source);_strcpy实现&#xff1a; char*…

指针 基础知识

本笔记为观看56 指针-指针的定义和使用_哔哩哔哩_bilibili后的学习笔记 指针的定义和使用 1、定义指针 int main () {//1、定义指针int a 10;//指针定义的语法&#xff1a; 数据类型 * 指针变量名&#xff1b;int * p;//让指针记录变量a的地址p &a; //& 为取址符cou…

学习Python的第四天

使用工具 PyCharm Community Edition 2023.3.4 使用环境 Python3.10.4 目录 1.字面量 1.1 值的类型 1.2 字面量的写法 2.注释 2.1 注释的作用 2.2 单行注释 2.2.1 语法 2.3 多行注释 2.3.1 语法 2.3.2 一般用来解释 2.4 注释示例 2.4.1 运行结果 3.变量 3.1…