C++基础篇(2)
目录
前言
1.缺省参数
2.函数重载
2.1函数重载的基本规则
编辑2.2注意事项
2.3 重载解析(Overload Resolution)--补充内容
3.引用
3.1引用的概念和定义
3.2引用的特性
3.3引用的使用
3.4const引用
4.指针和引用的关系
结束语

前言
上节小编讲解了命名空间和函数的输入输出,本节将讲解缺省参数,函数重载等知识。
1.缺省参数
缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参,则采用该形参的缺省值,否则使用指定的实参,缺省参数分为全缺省和半缺省参数。(有些地方把缺省参数也叫默认参数)
void func(int a, double b = 3.14, const char* c = "default") { // 正确// 函数体
}void func(int a = 1, double b, const char* c = "default") { // 错误,不能跳过 b// 函数体
}
#include <iostream>
using namespace std;
void func(int x=0) {cout << x << endl;
}
int main() {
// 没有传参时,使⽤参数的默认值
// 传参时,使⽤指定的实参func();func(10);return 0;
} 运行结果:
0
10
#include <iostream>
using namespace std;
// 全缺省
void Func1(int a = 10, int b = 20, int c = 30)
{cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl << endl;
}
// 半缺省
void Func2(int a, int b = 10, int c = 20)
{cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl << endl;
}
int main()
{Func1();Func1(1);Func1(1, 2);Func1(1, 2, 3);Func2(100);Func2(100, 200);Func2(100, 200, 300);Func2(100, ,300);//错误return 0;
}

// 在头文件中的函数声明
void func(int a = 1, double b = 3.14, const char* c = "default");// 在源文件中的函数定义
void func(int a, double b, const char* c) {// 函数体
}
2.函数重载
在C++中,函数重载(Function Overloading)是指在同一作用域内可以存在多个同名函数,但这些函数的参数列表(参数的个数、类型或者顺序)必须不同。编译器会根据传递给函数的参数来决定调用哪一个重载版本。
2.1函数重载的基本规则
1.参数数量不同:函数可以具有不同数量的参数。
#include <iostream>
using namespace std;
int Add(int a, int b) {return a + b;
}int Add(int a, int b, int c) { return a + b + c;
}int main() {int sum1 = Add(10, 20); double sum2 = Add(10,20,30); cout << "sum1: " << sum1 << endl;cout << "sum2: " << sum2 << endl;return 0;
}

2. 参数类型不同:函数可以具有不同类型的参数。
#include <iostream>
using namespace std;
int add(int a, int b) {cout << "int add(int a, int b)"<<endl;return a + b;}
double add(double a, double b) {cout << "double add(double a, double b)"<<endl;return a + b;}
int main() {int sum1 = add(10, 20); double sum2 = add(1.5, 2.5); cout << "sum1: " << sum1 << endl;cout << "sum2: " << sum2 << endl;return 0;
}

3. 参数顺序不同:如果参数类型相同,但顺序不同,也可以构成重载。
#include <iostream>
using namespace std;
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() {f(10, 'c');f('c', 10);return 0;
}

2.2注意事项
- 返回类型:函数重载与返回类型无关,即不能仅通过改变返回类型来重载函数。
-默认参数:使用默认参数的函数可能会导致重载解析的歧义,应当小心使用。
int Add(int a, int b) {return a + b;
}double Add(int a, int b) { // 错误:不能仅通过返回类型来重载return static_cast<double>(a + b);
}
#include <iostream>
using namespace std;// 下⾯两个函数构成重载
// f()但是调⽤时,会报错,存在歧义,编译器不知道调⽤谁
void f()
{cout << "f()" << endl;
}
void f(int a = 10)
{cout << "f(int a)" << endl;
}
int main() {f();return 0;
}

2.3 重载解析(Overload Resolution)--补充内容
当调用一个重载函数时,编译器会根据提供的实参和每个重载函数的形参列表进行匹配,以确定调用哪一个函数。这个过程称为重载解析。如果编译器无法明确地确定应该调用哪个函数,或者找到多个合适的匹配,就会产生编译错误。
函数重载是C++多态性的一种形式,它允许程序员使用相同的名字来执行相似的操作,这增强了代码的清晰性和可读性。
3.引用
3.1引用的概念和定义
在 C++ 中,引用是一个变量的别名。一旦一个引用被初始化为指向一个对象,它就不能被重新绑定到另一个对象。这与指针不同,指针可以在任何时候指向不同的对象。
引用的概念
- 别名:引用为另一个变量提供了一个额外的名字,它和原变量指向相同的内存位置。
- 不可变性:一旦引用被初始化,它就不能被重新赋值为另一个变量的引用。
- 无需解引用:使用引用时,不需要像指针一样使用
*操作符来访问引用的值。 - 效率:引用在传递参数时可以避免不必要的复制,特别是对于大型对象来说,使用引用可以提高效率。
引用的定义
引用在 C++ 中是这样定义的:
类型 &引用名 = 原变量名;
一些有趣的实例:
这里,类型 是原变量的类型,& 符号用于声明引用,引用名 是你给引用起的名字,而 原变量名 是已经存在的变量。

#include <iostream>
using namespace std;
int main() {int a = 520;int& b = a;int& c = a;int& d = b;++d;
// 引⽤:b和c是a的别名cout << &a << endl;cout << &b << endl;cout << &c << endl;
// 也可以给别名b取别名,d相当于还是a的别名cout << &d << endl;
//地址,值都是一样的cout << a << endl;cout << b << endl;cout << c << endl;cout << d << endl;return 0;
}

3.2引用的特性
• 引用在定义时必须初始化• 一个变量可以有多个引用• 引用一旦引用一个实体,再不能引用其他实体
#include<iostream>
using namespace std;
int main()
{int a = 10;// 编译报错:“ra”: 必须初始化引⽤//int& ra;int& b = a;int c = 20;// 这⾥并⾮让b引⽤c,因为C++引⽤不能改变指向,// 这⾥是⼀个赋值b = c;cout << a << endl;cout << b << endl;cout << c << endl;b = 30;cout << &a << endl;cout << &b << endl;cout << &c << endl;cout << a << endl;cout << b << endl;cout << c << endl;return 0;
}

3.3引用的使用
1.引用在实践中主要是于引用传参和引用做返回值中减少拷贝提高效率和改变引用对象时同时改变被引用对象。2.引用传参跟指针传参功能是类似的,引用传参相对更方便一些。3.引用返回值的场景相对比较复杂,小编实力有限,以后等知识丰富了再会详细讲解。4.引用和指针在实践中相辅相成,功能有重叠性,但是各有特点,互相不可替代。C++的引用跟其他语言的引用(如Java)是有很大的区别的,除了用法,最大的点,C++引用定义后不能改变指向,java的引用可以改变指向。5.一些主要用C代码实现版本数据结构教材中,使用C++引用替代指针传参,用的是简化程序,避开复杂的指针。
#include <iostream>
using namespace std;
void Swap(int& x, int& y) {int temp = x;x = y;y = temp;
}
int main() {int x = 520, y = 1314;cout << x << " " << y << endl;Swap(x, y);cout << x << " " << y << endl;return 0;
} 
#include<iostream>
#include <assert.h>
#include <stdlib.h> using namespace std;
typedef int STDataType;
typedef struct Stack {STDataType* a;int top;int capacity;
} ST;void STInit(ST& rs, int n = 4) {rs.a = (STDataType*)malloc(n * sizeof(STDataType));rs.top = 0; // 栈顶初始化为 0,表示栈为空rs.capacity = n;
}void STPush(ST& rs, STDataType x) {// 满了,扩容if (rs.top == rs.capacity) {printf("扩容\n");int newcapacity = rs.capacity == 0 ? 4 : rs.capacity * 2;STDataType* tmp = (STDataType*)realloc(rs.a, newcapacity * sizeof(STDataType));if (tmp == NULL) {perror("realloc fail");return;}rs.a = tmp;rs.capacity = newcapacity;}rs.a[rs.top] = x; rs.top++; // 栈顶指针上移
}int& STTop(ST& rs) {assert(rs.top > 0); // 确保栈不为空return rs.a[rs.top - 1]; // 返回栈顶元素的引用
}int main() {ST st1;STInit(st1);STPush(st1, 1);STPush(st1, 2);cout << STTop(st1) << endl; // 输出栈顶元素 2STTop(st1) += 10; // 通过引用修改栈顶元素cout << STTop(st1) << endl; // 输出修改后的栈顶元素 12return 0;
}

3.4const引用
在 C++ 中,
const引用是一种特殊类型的引用,它被用来引用一个对象,同时保证这个引用不会修改所引用的对象。这种引用通常用于函数参数,以允许函数读取传递的对象,但不允许通过引用修改它。
以下是 const 引用的几个关键点:
声明 const 引用
const 类型 &引用名 = 引用的对象;
这里,类型 是被引用对象的类型,引用名 是你给引用起的名字,而 引用的对象 是你想要引用的实际对象。
使用 const 引用的好处
- 保护数据不被修改:通过
const引用,你可以确保传递给函数的参数不会被函数修改。- 可以引用临时对象和字面量:
const引用可以引用右值(如字面量或临时对象),这是非const引用无法做到的。- 可以与任何类型的对象兼容:只要类型可以转换为
const引用的类型,就可以创建const引用。
示例
不需要注意的是类似 int& rb = a*3; double d = 12.34; int& rd = d; 这样一些场景下a*3的和结果保存在一个临时对象中, int& rd = d 也是类似,在类型转换中会产生临时对象存储中间值,也就是时,rb和rd引用的都是临时对象,而C++规定临时对象具有常性,所以这里就触发了权限放大,必须要用常引用才可以。
int main()
{
const int a = 10;
// 编译报错:error C2440: “初始化”: ⽆法从“const int”转换为“int &”
// 这⾥的引⽤是对a访问权限的放⼤
//int& ra = a;
// 这样才可以
const int& ra = a;
// 编译报错:error C3892: “ra”: 不能给常量赋值
//ra++;
// 这⾥的引⽤是对b访问权限的缩⼩
int b = 20;
const int& rb = b;
// 编译报错:error C3892: “rb”: 不能给常量赋值
//rb++;
return 0;
} #include<iostream>
using namespace std;
int main()
{
int a = 10;
const int& ra = 30;
// 编译报错: “初始化”: ⽆法从“int”转换为“int &”
// int& rb = a * 3;
const int& rb = a*3;
double d = 12.34;
// 编译报错:“初始化”: ⽆法从“double”转换为“int &”
// int& rd = d;
const int& rd = d;
return 0;
} #include <iostream>
using namespace std;void print(const int& x) {cout << x << endl;// x = 5; // 错误:不能通过 const 引用修改对象
}int main() {int a = 10;const int& ref = a; // 创建一个对 a 的 const 引用// ref = 20; // 错误:不能通过 const 引用修改对象print(a); // 正确:传递 intprint(20); // 正确:传递字面量,通过 const 引用允许return 0;
}
注释前的错误:

正确运行结果:

注意事项
- 一旦
const引用被初始化,它就不能再引用其他对象。 const引用不能引用非const对象的地址,如果需要引用非const对象,必须显式地声明非const引用。
总之,const 引用在 C++ 中是一种非常有用的特性,它不仅提供了对数据的保护,还增加了代码的灵活性和安全性。
4.指针和引用的关系
• 语法概念上引用是一个变量的取别名不开空间,指针是存储一个变量地址,要开空间。• 引用在定义时必须初始化,指针建议初始化,但是语法上不是必须的。• 引用在初始化时引用一个对象后,就不能再引用其他对象;而指针可以在不断地改变指向对象。• 引用可以直接访问指向对象,指针需要解引用才是访问指向对象。• sizeof中含义不同,引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占4个字节,64位下是8byte)• 指针很容易出现空指针和野指针的问题,引用很少出现,引用使用起来相对更安全一些。
结束语
本篇博客也就到此结束啦,C++ 的入门也差不多了,下个阶段我们将步入类和对象的学习!!!最后支持小编的友友和大佬们点个赞吧,也欢迎大家在评论区多多交流,感谢大家的支持!!!

相关文章:
C++基础篇(2)
目录 前言 1.缺省参数 2.函数重载 2.1函数重载的基本规则 编辑2.2注意事项 2.3 重载解析(Overload Resolution)--补充内容 3.引用 3.1引用的概念和定义 3.2引用的特性 3.3引用的使用 3.4const引用 4.指针和引用的关系 结束语 前言 上节小编…...
c++ primer plus 第16章string 类和标准模板库,16.1.3 使用字符串
c primer plus 第16章string 类和标准模板库,16.1.3 使用字符串 c primer plus 第16章string 类和标准模板库,16.1.3 使用字符串 文章目录 c primer plus 第16章string 类和标准模板库,16.1.3 使用字符串16.1.3 使用字符串程序清单16.3 hangman.cpp 16.1.3 使用字符串 现在&a…...
使用mybatis的statementHander拦截器监控表和字段并发送钉钉消息
新建mybatis的statementHander拦截器拦截器 类 面试题: 2.实现 解析Sql时引入JSqlParser JSqlParser 是一个 SQL 语句解析器。 它将 SQL转换为可遍历的 Java 类层次结构。 <dependency><groupId>com.github.jsqlparser</groupId><artifac…...
信贷系统——基础信贷概念
摘要 信贷是金融领域中的一个重要概念,指的是金融机构(如银行、信用合作社等)向个人、企业或政府提供资金的过程。在信贷过程中,金融机构向借款人提供资金,借款人则承诺在未来的某个时间点按照约定的条件和利率偿还借款。这种借款通常是在合同中明确约定的,包括贷款金额、…...
分页查询及其拓展应用案例
分页查询 分页查询是处理大量数据时常用的技术,通过分页可以将数据分成多个小部分,方便用户逐页查看。SQLAlchemy 提供了简单易用的方法来实现分页查询。 本篇我们也会在最终实现这样的分页效果: 1. 什么是分页查询 分页查询是将查询结果按照…...
【UE5.1】NPC人工智能——02 NPC移动到指定位置
效果 步骤 1. 新建一个蓝图,父类选择“AI控制器” 这里命名为“BP_NPC_AIController”,表示专门用于控制NPC的AI控制器 2. 找到我们之前创建的所有NPC的父类“BP_NPC” 打开“BP_NPC”,在类默认值中,将“AI控制器类”一项设置为“…...
有关电力电子技术的一些相关仿真和分析:⑤交-直-交全桥逆变+全波整流结构电路(MATLAB/Siumlink仿真)
全桥逆变+全波整流结构 参数:Vin=500V, Vo=200V, T=2:1:1, RL=10Ω, fs=100kHz, L=1mH, C=100uF (1)给定输入电压,输出电压和主电路参数,仿真研究电路工作原理,分析工作时序; (2)调节负载电阻,实现电流连续和断续,并仿真验证; (3)调节占空比,分析占空比与电…...
记录一次Android推流、录像踩坑过程
背景: 按照需求,需要支持APP在手机息屏时进行推流、录像。 技术要点: 1、手机在息屏时能够打开camera获取预览数据 2、获取预览数据时进行编码以及合成视频 一、息屏时获取camera预览数据: ①Camera.setPreviewDisplay(SurfaceH…...
VsCode 与远程服务器 ssh免密登录
首先配置信息 加入下列信息 Host qb-zn HostName 8.1xxx.2xx.3xx User root ForwardAgent yes Port 22 IdentityFile ~/.ssh/id_rsa 找到自己的公钥,不带pub是私钥,打死都不能给别人。复制公钥 拿到公钥后,来到远程服务器 vim ~/.ss…...
7/13 - 7/15
vo.setId(rs.getLong("id"))什么意思? vo.setId(rs.getLong("id")); 这行代码是在Java中使用ResultSet对象(通常用于从数据库中检索数据)获取一个名为"id"的列,并将其作为long类型设置为一个对象…...
烟雾监测与太阳能源:实验装置在其中的作用
太阳光在烟雾中的散射效应研究实验装置是一款模拟阳光透过烟雾环境的设备。此装置能帮助探究阳光在烟雾中的传播特性、散射特性及其对阳光的影响。 该装置主要包括光源单元、烟雾发生装置、光学组件、以及系统。光源单元负责产生类似于太阳光的光线,通常选用高亮度的…...
QT下,如何获取控制台输入
最近工作中为了测试某个模块,需要把原先输入模块部分,改成控制台输入来方便测试。在QT中,我们可以使用 QTextStream 类来读取用户的输入来达到目的。下面是一个简单的例子: #include <QCoreApplication> #include <QTex…...
mybatis动态传入参数 pgsql 日期 Interval ,day,minute
mybatis动态传入参数 pgsql 日期 Interval 在navicat中,标准写法 SELECT * FROM test WHERE time > (NOW() - INTERVAL 5 day)在mybatis中,错误写法 SELECT * FROM test WHERE time > (NOW() - INTERVAL#{numbers,jdbcTypeINTEGER} day)报错内…...
常见CSS属性
常见CSS属性。 1. display: 定义:display 属性控制元素如何渲染在文档流中,影响了元素是否占用空间、位置及盒子模型的行为。 使用说明:它可以设置为如block, inline, inline-block, flex, grid, none等值,用于决定元素显示模式…...
WSL-Ubuntu20.04训练环境配置
1.YOLOv8训练环境配置 训练环境配置的话就仍然以YOLOv8为例,来说明如何配置深度学习训练环境。这部分内容比较简单,主要是安装miniAnaconda以及安装torch和torchvision. 首先是miniAnaconda的安装(参考官网的教程Miniconda — Anaconda ),执行…...
运维检查:mysql表自增id是否快要用完
数据库表中最大自增ID用完会报错。判断是否接近或达到自增ID类型的最大值: 对于MySQL中的自增ID,如果使用的是int类型,其无符号(unsigned)的最大值可以达到2^32 - 1,即4294967295。如果使用的…...
深入理解FFmpeg--libavformat接口使用(一)
libavformat(lavf)是一个用于处理各种媒体容器格式的库。它的主要两个目的是去复用(即将媒体文件拆分为组件流)和复用的反向过程(以指定的容器格式写入提供的数据)。它还有一个I/O模块,支持多种…...
坚持日更的意义何在?
概述 日更,就是每天更新一次或一篇文章。 坚持日更,就是坚持每天更新一次或一篇文章。 这里用了坚持,实际上不是恰当的表述,正确的感觉应该是让日更当作习惯,然后,让自己习惯每天去更新一篇文章。 日更…...
内容长度不同的div如何自动对齐展示
平时我们经常会遇到页面内容div结构相同页,这时为了美观我们会希望div会对齐展示,但当div里的文字长度不一时又不想写固定高度,就会出现div长度长长短短,此时实现样式可以这样写: .e-commerce-Wrap {display: flex;fle…...
Qt中https的使用,报错TLS initialization failed和不能打开ssl.lib问题解决
前言 在现代应用程序中,安全地传输数据变得越来越重要。Qt提供了一套完整的网络API来支持HTTP和HTTPS通信。然而,在实际开发过程中,开发者可能会遇到SSL相关的错误,例如“TLS initialization failed”,cantt open ssl…...
铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...
MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...
[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
css的定位(position)详解:相对定位 绝对定位 固定定位
在 CSS 中,元素的定位通过 position 属性控制,共有 5 种定位模式:static(静态定位)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)和…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
