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"…...

地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...

家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...

微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...

ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...