重生之我在21世纪学C++—函数与递归

news2025/1/15 14:58:52

一、函数是什么?

相信我们第一次接触函数是在学习数学的时候,比如:一次函数 y = kx + b ,k 和 b 都是常数,给一个任意的 x ,就会得到一个 y 值。

其实在 C++ 语言中就引入了函数(function)的概念,有些翻译为:子程序(子程序这种翻译更加准确一些)。

函数就是一个完成某项特定的任务的一小段代码,这段代码是有特殊的写法和调用方法的。

我们在前面学习的时候,就已经见过和接触过函数了,比如:main 函数、scanf 函数、printf 函数、pow 函数、sqrt 函数等等。

C++ 语言程序是由若干个小的函数组合而成的,也可以这样说:一个大的计算任务可以分解成若干个较小的函数(对应较小的任务)完成。同时一个函数如果能完成某项特定任务的话,这个函数也是可以复用的,这显著提高了软件开发的效率。

函数的好处:

(1)模块化开发,一个大的功能,总能拆分成各种子功能,每个子功能都可以设计成一个函数,每个函数可以作为一个独立的模块存在,这样程序的逻辑会更加清晰,逻辑关系会更加明确。

(2)代码可以复用,只要根据需要定义出一个函数,需要用到这个功能的地方,直接调用函数就行,这显著降低了代码的冗余,并提高了开发效率。

(3)方便多个程序员之间协作开发,方便程序的多个模块之间的互相交互。

(4)熟悉函数的使用之后,代码的编写、阅读、调试、维护都会变得更加容易。

二、函数的分类

在 C++ 中,函数一般分为库函数自定义函数

1、库函数

前面内容中学到的 printf 、 scanf 都是库函数。库函数标准库中提供的现成的函数,我们只要学会函数的功能,就可以直接使用。有了库函数,一些常见的功能就不需要程序员自己实现了,一定程度上提升了效率;同时库函数的质量和执行效率上都是更有保证的。

编译器的标准库中提供了一系列的库函数,这些库函数根据功能的划分,在不同的头文件中进行了声明。

2、自定义函数

在了解库函数之后,我们可以知道其实库函数的功能是有限的,在实际开发过程中还是得根据需要将代码封装成自定义的函数。自定义的函数就是自己设计和实现的函数

(1)函数的语法形式

ret_type fun_name(形式参数)

{
}

1)ret_type函数计算结果的类型,有时候返回类型可以是 void ,表示什么都不返回。
2)fun_name 是函数名,函数有了名字就方便调用,所以函数名尽量要根据函数的功能来起,要起的有意义。
3)函数的参数就相当于工厂加工需要的原材料,函数的参数可以是 void明确表示函数没有参数。如果有参数,多个参数用逗号隔开,每个参数要分别交代清楚参数的类型名字
4){} 括起来的部分被称为函数体,函数体就是完成计算的过程

(2)函数定义

函数的实现就是函数的定义

函数的参数部分需要交代清楚:参数个数,每个参数的类型是啥,形参的名字叫啥。

以定义一个加法函数为例:

给加法函数取名: Add ,函数 Add 需要接收2个整型类型的参数,函数计算的结果是整型,即返回一个整型。

三、函数参数和返回值

1、实参和形参

实际上,在函数定义和使用的过程中,函数的参数被分为两种:

1)实际参数,简称实参

2)形式参数,简称形参

(1)实参

实际参数就是真实传递给函数的参数

(2)形参

形式参数没有使用的时候是不会向内存申请空间的,不是真实存在的。形式参数只有在函数被调用的过程中为了存放实参传递过来的值,才会向内存申请空间,这个过程就是形参的实例化

(3)实参和形参的关系

形参是实参的一份临时拷贝。形参和实参各自是独立的内存空间。

2、函数传参

(1)数组做函数参数

在使用函数解决问题的时候,难免会将数组作为参数传递给函数,在函数内部对数组进行操作。

我们需要知道的是:

1)函数的实参的名字和形参的名字可以相同,也可以不同
2)函数的形式参数要和函数的实参个数匹配
3)函数的实参是数组,形参也写成数组形式的;
4)形参如果是一维数组数组大小可以省略不写
5)形参如果是二维数组行可以省略,但是列不能省略
6)数组传参,形参是不会创建新的数组的;
7)形参操作的数组和实参的数组是同一个数组

比如:

(2)字符串做函数参数

如果将字符串做函数参数,直接在形参的部分使用字符串来接收。这里的形参是实参的一份临时拷贝,对形参的修改不能影响实参

比如:

(3)全局变量不用传参

全局变量的作用域很大,在整个程序中都可以使用,那么只要把变量、数组等定义成全局变量,如果要在函数中使用,就可以不用传参。当然,有时候将变量或者数组定义成全局的时候,是不能解决问题的,比如递归等场景,这时候,定义成全局变量反而会出现问题,所以就得考虑传参的问题。

3、返回值

(1)return 后边可以是一个数值,也可以是一个表达式,如果是表达式则先执行表达式,再返回表达式的结果。函数返回的值,可以使用变量来接收,如果不需要这个返回值,也可以不接收

(2)return 后边可以什么都没有,直接写 return; 这种写法适合函数返回类型是 void 的情况。

(3)return 返回的值和函数返回类型不一致,系统会自动将返回的值的类型隐式转换为函数的返回类型

(4)如果函数中 return 语句被执行,则函数直接返回,即使函数中 return 语句后还有其他代码也不再执行。

四、函数的声明和调用

1、函数声明

(1)函数要满足先声明后使用。函数声明只需要在函数调用之前就可以,可以在全局声明也可以局部声明。

(2)函数的定义是一种特殊的声明。函数声明中的形参的变量名可以省略掉只保留类型就可以(因为函数声明是不会使用这个函数的,所以不需要规定形参的名字)。

2、函数调用

函数调用的方式,一般会分为两类:传值调用传址(引用)调用

(1)传值调用

传值调用就是将实参的数据直接传递给形参。对形参的修改,不会影响实参。这种情况下参数传递的方式只能从实参到形参,也就是单向传递

传值调用一般应用的场景是:仅需要通过传参的方式将实参的值传递给被调函数,被调函数就可以完成工作,而不需要改变实参的值。

(2)引用

1)引用概念

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

引用使用格式:

类型 & 引用变量名 = 引用实体;

举例:

2)引用特性

1.引用在定义时必须初始化
2.一个变量可以有多个引用
3.引用一旦引用一个实体,再不能引用其他实体

(3)传址(引用)调用

传引用调用方式的本质是将实参变量的地址传递给了形参,而形参使用指针直接找到实参来进行操作。

举例:

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

在采用传值调用的过程中,实参传递给形参的时候,形参会创建新的空间,再将实参的数据给形参拷贝一份。但是引用传参的方式,就不存在数据的拷贝,只是在形参的部分建立引用的关系,形参就是实参

所以引用传参的效率要高于传值调用的方式。

五、函数重载

C++中的函数重载(Function Overloading)是指在同一个作用域中可以有多个同名函数, 它们的函数名称相同,但是参数列表不同

函数返回类型 函数名(参数1, 参数2,...);

这里的 “不同” 指的是参数的数量类型顺序至少有一个不同。函数的返回类型并不影响函数的重载,因为 C++ 编译器不会根据返回类型来区分不同的函数

举例:

六、递归

1、递归的概念

递归是一种在计算机科学中非常重要的编程技术,它可以简化许多复杂的问题。递归具体是指函数在定义的时候直接或间接调用自身的方式

2、递归的思想

递归可以把一个大型复杂问题层层转化为一个与原问题相似,但规模较小的子问题来求解;直到子问题不能再被拆分,可以直接求解,递归就结束了。递归的思考方式就是把大事化小的过程。
递归中的就是递推的意思,就是回归的意思。

3、递归的必要条件

递归在书写的时候,有2个必要条件:

(1)递归存在限制条件,当满足这个限制条件的时候,递归便不再继续。

(2)每次递归调用之后都会越来越接近这个限制条件

4、递归的举例

详见:

C语言函数递归-CSDN博客

5、递归与循环(迭代)的比较

首先我们需要知道:

在 C++ 中每一次函数调用,都需要为本次函数调用在内存的栈区,申请一块内存空间来保存函数调用期间的各种局部变量的值,这块空间被称为运行时堆栈,或者函数栈帧
函数不返回,函数对应的栈帧空间就一直占用,所以如果函数调用中存在递归调用的话,每一次递归函数调用都会开辟属于自己的栈帧空间,直到函数递归不再继续,开始回归,才逐层释放栈帧空间
所以如果采用函数递归的方式完成代码,递归层次太深,就会浪费太多的栈帧空间,也可能引起栈溢出(stack overflow)的问题。

我们看到的许多问题是以递归的形式进行解释的,这只是因为它比非递归的形式更加清晰,但是这些问题的迭代实现往往比递归实现效率更高。当一个问题非常复杂,难以使用迭代的方式实现时,此时递归实现的简洁性便可以补偿它所带来的运行时开销

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mac——Cpolar内网穿透实战

摘要 本文介绍了在Mac系统上实现内网穿透的方法,通过打开远程登录、局域网内测试SSH远程连接,以及利用cpolar工具实现公网SSH远程连接MacOS的步骤。包括安装配置homebrew、安装cpolar服务、获取SSH隧道公网地址及测试公网连接等关键环节。 1. MacOS打开…

Ubuntu中双击自动运行shell脚本

方法1: 修改文件双击反应 参考: https://blog.csdn.net/miffywm/article/details/103382405 chmod x test.sh鼠标选中待执行文件,在窗口左上角edit菜单中选择preference设计双击执行快捷键,如下图: 方法2: 设置一个应用 参考: https://blo…

力扣 全排列

回溯经典例题。 题目 通过回溯生成所有可能的排列。每次递归时,选择一个数字,直到选满所有数字,然后记录当前排列,回到上层时移除最后选的数字并继续选择其他未选的数字。每次递归时,在 path 中添加一个新的数字&…

arcgis提取不规则栅格数据的矢量边界

效果 1、准备数据 栅格数据:dem或者dsm 2、栅格重分类 分成两类即可 3、新建线面图层 在目录下选择预先准备好的文件夹,点击右键,选择“新建”→“Shapefile”,新建一个Shapefile文件。 在弹出的“新建Shapefile”对话框内“名称”命名为“折线”,“要素类型”选…

【DB-GPT】开启数据库交互新篇章的技术探索与实践

一、引言:AI原生数据应用开发的挑战与机遇 在数字化转型的浪潮中,企业对于智能化应用的需求日益增长。然而,传统的数据应用开发方式面临着诸多挑战,如技术栈复杂、开发周期长、成本高昂、难以维护等。这些问题限制了智能化应用的…

LVGL移植高通点阵字库GT30L24A3W

字库芯片: GT30L24A3W MCU:STM32F429 LVGL版本:V8.4 一、实现gt_read_data() 和 r_dat_bat() 请参考下面视频 如何在32位MCU上使用高通点阵字库_哔哩哔哩_bilibili 高通字库使用教程(1)硬件链接与注意事项部分_哔哩哔哩_bilibili 高通字库使用教程(2)SPI底层函数使用_哔哩…

一键掌握多平台短视频矩阵营销/源码部署

短视频矩阵系统的介绍与应用 随着数字化营销策略的不断演进,传统的短视频矩阵操作方法可能已显陈旧。为此,一款全新的短视频矩阵系统应运而生,它通过整合多个社交媒体账户、创建多样化的任务、运用先进的智能视频编辑工具、实现多平台内容的…

MySQL(高级特性篇) 06 章——索引的数据结构

一、为什么使用索引 索引是存储引擎用于快速找到数据记录的一种数据结构,就好比一本教科书的目录部分,通过目录找到对应文章的页码,便可快速定位到需要的文章。MySQL中也是一样的道理,进行数据查找时,首先查看查询条件…

源码安装httpd2.4

1、下载 wget https://archive.apache.org/dist/httpd/httpd-2.4.54.tar.gz 2.解压下载压缩包 tar -zxvf httpd-2.4.54.tar.gz cd httpd-2.4.54 3、安装httpd所需要的依赖 yum groupinstall "Development Tools" -y 4.配置httpd ./configure --prefix/usr/local/htt…

【算法学习】——整数划分问题详解(动态规划)

🧮整数划分问题是一个较为常见的算法题,很多问题从整数划分这里出发,进行包装,形成新的题目,所以完全理解整数划分的解决思路对于之后的进一步学习算法是很有帮助的。 「整数划分」通常使用「动态规划」解决&#xff0…

文件与IO流:一

一些常识 硬盘特点 擅长顺序读,不擅长随机读,尤其是机械硬盘。 随机读例如某个目录中的所有小文件的复制,顺序读是某个大文件的整体复制。 windows的文件系统是按照“树形结构”来组织文件。 路径的风格 1.绝对路径:从根节点…

计算机网络 (42)远程终端协议TELNET

前言 Telnet(Telecommunication Network Protocol)是一种网络协议,属于TCP/IP协议族,主要用于提供远程登录服务。 一、概述 Telnet协议是一种远程终端协议,它允许用户通过终端仿真器连接到远程主机,并在远程…

WPF系列十二:图形控件CombinedGeometry

简介 CombinedGeometry 是 WPF (Windows Presentation Foundation) 中的一个几何对象,用于将两个几何图形组合成一个新的几何图形。它允许你通过不同的组合模式(如相交、并集、差集或异或)来创建复杂的形状。常与 Path 控件一起使用来绘制组…

《计算机网络》课后探研题书面报告_网际校验和算法

网际校验和算法 摘 要 本文旨在研究和实现网际校验和(Internet Checksum)算法。通过阅读《RFC 1071》文档理解该算法的工作原理,并使用编程语言实现网际校验和的计算过程。本项目将对不同类型的网络报文(包括ICMP、TCP、UDP等&a…

业务幂等性技术架构体系之接口幂等深入剖析

在实际应用中,由于网络不稳定、系统延迟等原因,客户端可能会重复发送相同的请求。如果这些重复请求都被服务器处理并执行,就可能导致意想不到的问题,比如重复扣款、多次下单或者数据不一致等。 这就是为什么我们需要接口幂等性。…

sql模糊关联匹配

需求目标: 建立临时表 drop table grafana_bi.zbj_gift_2024;USE grafana_bi; CREATE TABLE zbj_gift_2024 (id INT AUTO_INCREMENT PRIMARY KEY,userName VARCHAR(255),giftName VARCHAR(255),giftNum INT,points INT,teacher VARCHAR(255),sendDate DATETIME,…

《蜜蜂路线》

题目背景 无 题目描述 一只蜜蜂在下图所示的数字蜂房上爬动,已知它只能从标号小的蜂房爬到标号大的相邻蜂房,现在问你&#xff1a;蜜蜂从蜂房 mm 开始爬到蜂房 nn&#xff0c;m<nm<n&#xff0c;有多少种爬行路线&#xff1f;&#xff08;备注&#xff1a;题面有误&am…

LeetCode100之搜索二维矩阵(46)--Java

1.问题描述 给你一个满足下述两条属性的 m x n 整数矩阵&#xff1a; 每行中的整数从左到右按非严格递增顺序排列。每行的第一个整数大于前一行的最后一个整数。 给你一个整数 target &#xff0c;如果 target 在矩阵中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回…

JS爬虫实战演练

在这个小红书私信通里面进行一个js的爬虫 文字发送 async function sendChatMessage(content) {const url https://pro.xiaohongshu.com/api/edith/ads/pro/chat/chatline/msg;const params new URLSearchParams({porch_user_id: 677e116404ee000000000001});const messageD…

自动连接校园网wifi脚本实践(自动网页认证)

目录 起因执行步骤分析校园网登录逻辑如何判断当前是否处于未登录状态&#xff1f; 书写代码打包设置开机自动启动 起因 我们一般通过远程控制的方式访问实验室电脑&#xff0c;但是最近实验室老是断电&#xff0c;但重启后也不会自动连接校园网账户认证&#xff0c;远程工具&…