C++基础知识【4】函数及参数
目录
一、函数的基本概念
1.1、构成
1.2、声明和定义
1.3、函数的调用
二、参数
2.1、形参和实参
2.2、参数的传递
传值
传引用
传指针
三、C++函数的一些新特性
3.1、Lambda表达式
3.2、右值引用
3.3、默认参数
3.4、变长参数模板
3.5、constexpr函数
3.6、noexcept函数
四、C++内联函数
五、函数的重载
一、函数的基本概念
C++函数是一段可重用的代码,用于执行特定的任务。它可以接受输入参数、执行一些操作,最后返回一个值。函数可以通过模块化编程来简化代码,提高代码的可读性和可维护性。函数也被称作方法。
函数分为库函数(也称标准函数库或系统函数库)和自定义函数两种。
库函数是指在C++标准库或其他系统库中提供的函数,通常包含在头文件中。C++标准库中包含了很多常用的函数和数据类型,例如字符串处理、输入输出、数学计算、容器和算法等等。开发者可以直接使用这些库函数,而无需重新编写代码,从而提高开发效率和代码可读性。
自定义函数是由开发者自行编写的函数,用于实现特定的功能。自定义函数可以在程序中多次调用,避免了代码的重复编写。自定义函数的定义可以在main函数之前或之后,甚至在其他文件中,只要在使用函数之前有函数声明即可。
本文主要解释自定义函数。
1.1、构成
函数的构成:
返回类型 函数名(参数列表) {函数体return 返回值;}
其中:
- 函数名:函数名是函数的标识符,用于标识函数并区分其他函数。在C++中,函数名由字母、数字和下划线组成,不能以数字开头。
- 参数列表:参数列表是一组用逗号分隔的变量,函数在执行时需要这些变量的值。C++中的函数可以有零个或多个参数,参数可以有默认值,也可以是引用类型。
- 返回类型:返回类型指定函数返回的值的类型。C++中的函数可以返回任何类型的值,包括基本数据类型、结构体、类、指针等。
- 函数体:函数体是包含一组语句的代码块,它定义了函数要执行的操作。
1.2、声明和定义
函数可以先声明再定义,或者直接定义。函数的声明和定义可以分别在不同的源文件中实现,这种方式可以方便地实现模块化编程和代码复用。
函数声明:函数声明通常包括函数名、参数列表和返回类型,它告诉编译器这个函数的存在和类型,以便编译器在调用该函数时能够正确地生成调用代码。函数声明可以出现在头文件中,也可以在函数定义之前进行。
函数定义:函数定义包括函数名、参数列表、返回类型和函数体,它实现了函数的具体功能。函数定义必须出现在程序的某个位置,通常放在源文件的末尾。
以下是一个使用函数声明和定义的例子:
// 声明函数int addFun(int x, int y);// 定义函数int addFun(int x, int y) {return x + y;}
1.3、函数的调用
C++函数通过函数名和参数列表来调用。调用函数时,需要将实际参数传递给函数。实际参数是调用函数时提供的参数。
以下是调用函数的语法:
函数名(实际参数列表);
例如,要调用上面定义的 addFun 函数,可以这样写:
int main() {int a = 10, b = 20;int c = addFun(a, b);return 0;}
二、参数
2.1、形参和实参
C++函数的参数分为形式参数和实际参数。形式参数是定义在函数声明或定义中的参数,也称为形参。实际参数是在调用函数时传递给函数的值或变量,也称为实参。
需要注意的是,函数的实参可以是常量、变量、表达式、指针、引用等类型,而函数的形参通常是变量或引用类型。在函数调用时,实参会被传递给形参,如果实参和形参的类型不匹配,编译器会尝试进行类型转换。如果无法进行类型转换,编译器将会报错。
此外,C++还支持默认参数,它允许在函数定义时为某些参数设置默认值,这样在函数调用时可以省略这些参数。例如:
int addFun(int a, int b = 0) {return a + b;}int main() {int x = 10, y = 20;int result1 = addFun(x); // b参数使用默认值0int result2 = addFun(x, y); // b参数使用传递的实参yreturn 0;}
2.2、参数的传递
C++支持三种参数传递方式:传值、传引用或传指针。
传值
传值是将实际参数的值复制到形式参数的过程。在函数中修改形式参数的值不会影响实际参数的值。这种方式适用于参数较少、参数类型简单的情况,也是使用最广泛的情况。
以下是传值调用的示例:
void addplus(int a) {a++; // 修改形式参数的值}int main() {int x = 10;addplus(x); // 传递 x 的值cout << x << endl; // 输出 10,x 的值没有改变return 0;}
传引用
传引用是指将实参的地址传递给形参,函数内部可以直接操作实参的值。传引用方式可以避免复制大量的数据,提高程序的效率。传引用方式使用引用符号 & 定义形参。
以下是传引用的示例:
void addplus(int& a) {a++; // 通过引用修改实际参数的值}int main() {int x = 10;addplus(x); // 传递 x 的别名cout << x << endl; // 输出 11,x 的值已经被修改return 0;}
传指针
传指针是指将实参的地址传递给形参,函数内部可以通过指针来操作实参的值。传指针方式可以与传引用方式相比,更加灵活,但需要注意指针为空的情况。传指针方式使用指针符号 * 定义形参。
以下是传指针的示例:
void addplus(int* a) {(*a)++; // 通过指针修改实际参数的值
}int main() {int x = 10;addplus(&x); // 传递 x 的地址cout << x << endl; // 输出 11,x 的值已经被修改return 0;
}
注意,传引用通常比传指针更易于使用和更安全,因为它可以防止空指针异常。
三、C++函数的一些新特性
3.1、Lambda表达式
Lambda表达式是一种匿名函数,可以在需要时快速创建一个函数对象。Lambda表达式可以访问它所在函数的变量,这使得它们非常灵活和有用。
以下是一个使用Lambda表达式的例子:
#include <iostream>
#include <vector>
#include <algorithm>int main() {std::vector<int> nums = {1, 2, 3, 4, 5};std::for_each(nums.begin(), nums.end(), [](int num) {std::cout << num << " ";});return 0;
}
在这个例子中,Lambda表达式被传递给了std::for_each算法,用于输出向量中的所有元素。Lambda表达式的参数类型和返回类型都可以被自动推断出来。
3.2、右值引用
右值引用是一种新的引用类型,可以将右值转换为左值,并提高代码的性能和效率。
以下是一个使用右值引用的例子:
#include <iostream>
#include <string>std::string&& foo(std::string& str) {return std::move(str);
}int main() {std::string str = "hello, world!";std::string&& rstr = foo(str);std::cout << rstr << std::endl;return 0;
}
在这个例子中,foo函数返回一个右值引用,将传递给它的字符串转换为右值。在main函数中,我们使用一个右值引用变量来接收foo函数的返回值,并输出它。
3.3、默认参数
默认参数允许在函数定义中为某些参数设置默认值,在函数调用时可以省略这些参数。
以下是一个使用默认参数的例子:
#include <iostream>
#include <string>void foo(std::string str = "hello, world!") {std::cout << str << std::endl;
}int main() {foo(); // 输出:hello, world!foo("hi, there!"); // 输出:hi, there!return 0;
}
在这个例子中,foo函数的参数str被设置了默认值"hello, world!"。当我们在main函数中调用foo函数时,如果不传递任何参数,则使用默认值;否则,使用传递的参数值。
3.4、变长参数模板
可变参数模板允许在函数中使用任意数量的参数,这对于处理不定数量的参数非常有用。
以下是一个使用可变参数模板的例子:
#include <iostream>
#include <string>template <typename T>
void print(T arg) {std::cout << arg << std::endl;
}template <typename T, typename... Args>
void print(T arg, Args... args) {std::cout << arg << " ";print(args...);
}int main() {print("hello", "world", "!");print(1, 2, 3, 4, 5);return 0;
}
3.5、constexpr函数
constexpr函数是一种特殊的函数,可以在编译时求值,这可以提高程序的效率和性能。
以下是一个使用constexpr函数的例子:
#include <iostream>constexpr int factorial(int n) {return n <= 1 ? 1 : n * factorial(n - 1);
}int main() {constexpr int n = 5;constexpr int result = factorial(n);std::cout << result << std::endl;return 0;
}
3.6、noexcept函数
noexcept函数是一种指定函数不抛出异常的方法,这可以帮助编译器优化代码并提高程序的性能。
以下是一个使用noexcept函数的例子:
#include <iostream>
#include <vector>void foo(std::vector<int>& v) noexcept {v.push_back(42);
}int main() {std::vector<int> v = {1, 2, 3};foo(v);for (auto i : v) {std::cout << i << " ";}return 0;
}
四、C++内联函数
C++中,内联函数是一种特殊的函数,编译器会尝试将其在调用点直接展开,以避免函数调用的开销。
内联函数通常是通过在函数定义前加上inline关键字来定义的。在调用内联函数时,编译器会直接将函数体插入到调用点处,而不会生成函数调用的代码。这种展开的方式可以减少函数调用的开销,从而提高程序的性能。
需要注意的是,内联函数适用于函数体比较简单的函数。对于函数体比较复杂的函数,内联展开可能会导致代码膨胀,反而降低程序的性能。此外,编译器并不一定会将函数展开为内联函数,具体是否展开取决于编译器的实现。
下面是一个内联函数的例子:
inline int add(int a, int b) {return a + b;}
需要注意的是,内联函数仅仅是一种建议,编译器并不一定会将其展开为内联函数。
此外,对于在类定义中定义的成员函数,默认情况下也是内联函数,类定义中定义的成员函数会隐式地添加inline关键字。因此,对于类定义中定义的成员函数,不需要显式地添inline关键字。
五、函数的重载
C++中,函数重载(Function Overloading)指的是在同一个作用域内定义的具有相同名称但参数类型、个数或顺序不同的多个函数。在调用函数时,编译器会根据实参的类型、个数和顺序,自动选择合适的函数进行调用。
函数重载的优点在于可以方便地为函数提供不同的参数选项,同时能够避免函数名称冲突的问题。
下面是一个函数重载的例子:
int add(int a, int b) {return a + b;}double add(double a, double b) {return a + b;}int add(int a, int b, int c) {return a + b + c;}
需要注意的是,函数重载的区分是基于参数类型、个数和顺序的,而不是基于返回值类型的。因此,在定义函数时,不能只依据返回值类型的不同来进行函数重载。
相关文章:
C++基础知识【4】函数及参数
目录 一、函数的基本概念 1.1、构成 1.2、声明和定义 1.3、函数的调用 二、参数 2.1、形参和实参 2.2、参数的传递 传值 传引用 传指针 三、C函数的一些新特性 3.1、Lambda表达式 3.2、右值引用 3.3、默认参数 3.4、变长参数模板 3.5、constexpr函数 3.6、noex…...
约瑟夫森磁效应
电流与波函数的相位有直接的关系,可得约瑟夫森结的电流为 IIcsinϕ\begin{align} II_c sin\phi \end{align} IIcsinϕ 式中,IcI_cIc为临界电流,相位差为ϕϕ2−ϕ1\phi\phi_2-\phi_1ϕϕ2−ϕ1。 根据磁矢势A的定义,B…...

什么是L1和L2正则化,以及它们有什么区别
一、L1和L2正则化是什么? 在防止过拟合的方法中有L1正则化和L2正则化,L1和L2是正则化项,又叫做惩罚项,是为了限制模型的参数,防止模型过拟合而加在损失函数后面的一项。 在二维的情况下,黄色的部分是L2和…...

场景式消费激发春日经济,这些电商品类迎来消费热潮
春日越临近,商机越浓郁。随着气温渐升,春日经济已经潜伏在大众身边。“春菜”、“春装”、“春游”、“春季养生”等春日场景式消费走热。 下面,鲸参谋为大家盘点几个与春日经济紧密相关的行业。 •春日仪式之春游踏青 ——户外装备全面开花…...

[2.1.4]进程管理——进程通信
文章目录第二章 进程管理进程通信(IPC)为什么进程通信需要操作系统支持?(一)共享存储(1)基于存储区的共享(2)基于数据结构的共享(二)消息传递什么…...

ChatGPT也有犯晕的时候
前面测试 ChatGPT 进行写代码、优化代码、解释代码、一般问答都表现的很好。偷个懒,用ChatGPT 帮我写段生物信息代码如果 ChatGPT 给出的的代码不太完善,如何请他一步步改好?代码看不懂?ChatGPT 帮你解释,详细到爆&…...

机器学习与目标检测作业:连通块算法
机器学习与目标检测作业:连通块算法一、连通块算法题目描述二、连通块算法文件结构三、连通块算法程序编写3.1、连通块算法conBlock.h头文件内容3.2、conBlock.cpp源文件内容3.3.3、mian.h头文件内容3.3.4、main.cpp源文件内容如下四、连通块算法程序运行结果一、连…...
HBase基础 --- 增删查改
目录 创建表 查看指定表全名空间中的表 查看表描述 禁用/启用 查看禁用/启动状态 删除表 新增列族 删除列族 更改列族存储版本的限制 增加数据 根据条件查询 查看指定列中不同版本的数据 删除指定列族下的指定列 删除指定行 全表扫描 全表扫描指定列族…...

如何基于AI智能视频技术实现公园景区的人流量实时统计?
一、方案背景春暖花开的季节来临,外出旅游的人群也越来越多。无论是景区、公园、博物馆、步行街等场所,客流超载非常大,给游客带来的体验较差,同时也存在安全隐患。当前景区面临的管理痛点包括:客流信息查询难…...

【JavaWeb】Servlet详解
文章目录1. 前置知识2.servlet生命周期2.1 默认情况下,服务器启动时,servlet对象并没有被创建2.2 用户执行一次请求2.3用户执行第二次请求2.4 3,4,5,6....次请求2.5 关闭服务器3.servlet方法解析4.适配器模式改造servlet4.1不使用servlet模式4.2使用适配…...

谁是世界上最好的编程语言?--编程语言70年浅谈
1、编程语言发展史纵览 严谨起见,本文提到的编程语言指的是「第三代高级编程语言」。 首先,我们从时间维度入手聊聊编程语言。一图胜千言,我们从目前主流的编程语言中,挑选出流行的、具有历史影响力的语言。把它们按时间从上往下…...

Webpack前端资源加载/打包工具
文章目录一、Webpack1、什么是Webpack2、Webpack安装2.1全局安装2.2安装后查看版本号3、创建项目3.1初始化项目3.2创建src文件夹3.3 src下创建common.js3.4 src下创建utils.js3.5 src下创建main.js4、JS打包4.1创建配置文件4.2执行编译命令4.3创建入口页面4.4测试5、CSS打包5.1…...

springcloud3 fegin实现服务调用1
一 Fegin的作用 1.1 fegin的作用 fegin是一个声明式的web服务客户端,让编写web服务器客户端变得非常容易,只需创建一个接口并在接口中添加FeginClients注解即可。 Fegin的使用方式:使用fegin的注解定义接口,调用这个接口&#…...

专业版即将支持自定义场景测试
物联网 MQTT 测试云服务 XMeter Cloud 专业版于 2022 年底上线后,已有不少用户试用,对数千甚至上万规模的 MQTT 并发连接和消息吞吐场景进行测试。同时我们也收到了希望支持更多物联网协议测试的需求反馈。 新年伊始,XMeter 团队全力聚焦于 …...

Process Monitor工具使用实验(23)
实验目的 学习Process Monitor实用小工具的使用,学会利用Process Monitor工具观察程序进程/线程、文件系统、注册表、网络连接等的活动。预备知识 Process Monitor是一个Windows系统下先进的监视工具,它可以显示文件系统、注册表、网络连接、进程…...

钓鱼客服到拿下服务器全过程(重点在于钓鱼添加img src)
重点总结 钓鱼时主动在变量中添加了字段,等待用户点击获取ip信息进行下一步资金盘plus呢 左看右看没啥东西,看看客服系统能不能打xss。 吊毛客服居然不在线,这套客服系统见过是whisper,之前审计过没有存储xss 但能通过伪造图片…...

【C++】list迭代器的深度剖析及模拟实现(感受类封装,类和对象的思想)
早点睡兄弟,别一天到晚就熬夜。 文章目录一、通过list迭代器来感受类和对象以及类封装的思想1.迭代器的特征和本质是什么?(两大特征:类的内嵌类型,行为像指针。本质:内置类型定义的变量或自定义类型实例化…...

JavaScript 语句、注释和代码块实例集合
文章目录JavaScript 语句、注释和代码块实例集合JavaScript 语句JavaScript 代码块JavaScript 单行注释JavaScript 多行注释使用单行注释来防止执行使用多行注释来防止执行JavaScript 语句、注释和代码块实例集合 JavaScript 语句 源码 <!DOCTYPE html> <html> &…...

华为机试题:HJ103 Redraiment的走法(python)
文章目录(1)题目描述(2)Python3实现(3)知识点详解1、input():获取控制台(任意形式)的输入。输出均为字符串类型。1.1、input() 与 list(input()) 的区别、及其相互转换方…...

html+css 实现 熊猫样式
效果 html代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><meta http-equiv"X-UA-Compatible"…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...

汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...

什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...

HBuilderX安装(uni-app和小程序开发)
下载HBuilderX 访问官方网站:https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本: Windows版(推荐下载标准版) Windows系统安装步骤 运行安装程序: 双击下载的.exe安装文件 如果出现安全提示&…...

12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

DingDing机器人群消息推送
文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人,点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置,详见说明文档 成功后,记录Webhook 2 API文档说明 点击设置说明 查看自…...
作为测试我们应该关注redis哪些方面
1、功能测试 数据结构操作:验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化:测试aof和aof持久化机制,确保数据在开启后正确恢复。 事务:检查事务的原子性和回滚机制。 发布订阅:确保消息正确传递。 2、性…...