定义和使用自己的子程序——函数的介绍

定义和使用自己的子程序——函数的介绍

  • 1.函数基础语法
    • 1.1.基础语法
    • 1.2.例题1——距离函数
      • 题目描述
      • 输入格式
      • 输出格式
      • 输入输出样例
        • 输入 #1
        • 输出 #1
      • 提示
  • 2.void类型
  • 3.变量作用域和参数传递
    • 3.1.局部变量和全局变量
    • 3.2.形式参数和实际参数
    • 3.3.例题2——歌唱比赛
      • 题目描述
      • 输入格式
      • 输出格式
      • 输入输出样例
        • 输入 #1
        • 输出 #1
  • 4.递归函数
    • 4.1.递归函数介绍
    • 4.2.例题3——计算阶乘
      • 题目描述
      • 输入格式
      • 输出格式
      • 输入输出样例
        • 输入 #1
        • 输出 #1
      • 提示
    • 4.3.递归函数运行详细演示和代码
    • 4.4.练习1——赦免战俘
      • 题目背景
      • 题目描述
      • 输入格式
      • 输出格式
      • 输入输出样例
        • 输入 #1
        • 输出 #1
  • 5.基础宏函数
  • 6.课后作业

1.函数基础语法

1.1.基础语法

    在编写程序时,我们可能会遇到需要大量实现同一种功能的情况。如果能把它们分装成像ceil,sqrt这样的函数该多好啊。我们接下来就会学习函数的相关知识。

函数,又叫子函数,也可以被称为子程序。函数定义的基本语法如下:

返回值类型 函数名(参数类型1 参数名1,参数类型2 参数名2,…参数类型n 参数名n)
{
    函数体
    return 返回值;
}

1.2.例题1——距离函数

距离函数 - 洛谷

题目描述

给出平面坐标上不在一条直线上三个点坐标 ( x 1 , y 1 ) , ( x 2 , y 2 ) , ( x 3 , y 3 ) (x_1,y_1),(x_2,y_2),(x_3,y_3) (x1,y1),(x2,y2),(x3,y3),坐标值是实数,且绝对值不超过 100.00,求围成的三角形周长。保留两位小数。

对于平面上的两个点 ( x 1 , y 1 ) , ( x 2 , y 2 ) (x_1,y_1),(x_2,y_2) (x1,y1),(x2,y2),则这两个点之间的距离 d i s = ( x 2 − x 1 ) 2 + ( y 2 − y 1 ) 2 dis=\sqrt{(x_2-x_1)^2+(y_2-y_1)^2} dis=(x2x1)2+(y2y1)2

输入格式

输入三行,第 i i i 行表示坐标 ( x i , y i ) (x_i,y_i) (xi,yi),以一个空格隔开。

输出格式

输出一个两位小数,表示由这三个坐标围成的三角形的周长。

输入输出样例

输入 #1
0 0
0 3
4 0
输出 #1
12.00

提示

数据保证,坐标均为实数且绝对值不超过 100 100 100,小数点后最多仅有 3 3 3 位。

题意分析
如果我们直接编写程序,回得到这样的代码:

#include<cstdio>
#include<cmath>
using namespace std;
int main(){double x1,y1,x2,y2,x3,y3,ans;scanf("%lf%lf%lf%lf%lf%lf",&x1,&y1,&x2,&y2,&x3,&y3);ans=sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));//使用公式ans+=sqrt((x3-x2)*(x3-x2)+(y3-y2)*(y3-y2));ans+=sqrt((x3-x1)*(x3-x1)+(y3-y1)*(y3-y1));printf("%.2lf", ans);//保留两位小数return 0;
}

这样太啰嗦了,我们可以将计算两点的距离这个功能分装成一个函数。

#include<cstdio>
#include<cmath>
using namespace std;
double sq(double x)//每个子函数都必须定义在主函数外面
{return x*x;
}
double dist(double x1,double y1,double x2,double y2)//计算两点距离的函数
{return sqrt(sq(x1-x2)+sq(y1-y2));//调用前面定义过的函数
}
int main(){double x1, y1, x2, y2, x3, y3, ans;scanf("%lf%lf%lf%lf%lf%lf",&x1,&y1,&x2,&y2,&x3,&y3);ans=dist(x1,y1,x2,y2);//使用前面分装好的函数ans+=dist(x1,y1,x3,y3);ans+=dist(x2,y2,x3,y3);printf("%.2lf",ans);return 0;
}

注意:函数内的每个参数都必须注明类型,不可以出现这种形式:

double f(int x1,x2)
{return x1+x2;
}

    我们应该根据引用的顺序,确定函数定义的顺序。比如上文sq函数应在dist函数前面定义dist函数应在main函数前面定义。

2.void类型

    在C++中有一种特殊的类型:空类型。即void。现阶段可以理解为void只能用来定义函数,不能用来定义变量。void类型的函数不能有返回值,或者返回一个“”。void类型的函数通常只用来执行一些操作。比如:

void print_data(int a,int b)
{cout<<a<<" "<<b<<endl;
}void print_division(int a,int b)
{if(b==0){cout<<"除数不能为0";return;//提前返回}double ans=a*1.0/b;cout<<ans<<endl;
}

3.变量作用域和参数传递

3.1.局部变量和全局变量

    在C++中,定义在函数外部的就叫做全局变量。反之,定义在函数内部的就叫做局部变量

    全局变量会自动赋值为0

#include<iostream>
using namespace std;
int n,a[110];//这两个是全局变量
int add(int x)
{return x+1;
}
int main(){int v=0;//这是局部变量cin>>n;a[n]=add(a[n]);cout<<a[n]<<endl;
}

3.2.形式参数和实际参数

    全局变量和局部变量统称为为实际参数,简称“实参”。定义函数时括号内的参数都叫做形式参数,简称“形参”。
    在函数运行的过程中,并不是直接引用实参。而是将实参的值拷贝一份来使用。函数返回之后,所有的形参都会被销毁。所以函数括号内的参数都叫做形式参数

#include<iostream>
using namespace std;
int Add(int x,int y)//x和y是形参
{return x+y;
}
int main(){int a,b;//a和b是实参cin>>a>>b;cout<<Add(a,b);return 0;
}

3.3.例题2——歌唱比赛

歌唱比赛 - 洛谷

题目描述

n ( n ≤ 100 ) n(n\le 100) n(n100) 名同学参加歌唱比赛,并接受 m ( m ≤ 20 ) m(m\le 20) m(m20) 名评委的评分,评分范围是 0 0 0 10 10 10 分。这名同学的得分就是这些评委给分中去掉一个最高分,去掉一个最低分,剩下 m − 2 m-2 m2 个评分的平均数。请问得分最高的同学分数是多少?评分保留 2 2 2 位小数。

输入格式

第一行两个整数 n , m n,m n,m
接下来 n n n 行,每行各 m m m 个整数,表示得分。

输出格式

输出分数最高的同学的分数,保留两位小数。

输入输出样例

输入 #1
7 6
4 7 2 6 10 7
0 5 0 10 3 10
2 6 8 4 3 6
6 3 6 7 5 8
5 9 3 3 8 1
5 9 9 3 2 0
5 8 0 4 1 10
输出 #1
6.00

题意分析
    我们可以使用类似于“打擂台”的方法寻找最大最小值。设置一个初始擂主。遍历数组,如果找到的数比当前擂主大/小就更新擂主。然后我们分装一个函数,用来计算每位同学的分数

程序如下:

#include<cstdio>
#include<algorithm>
using namespace std; 
int n,m,s[10010],maxsum=-1;//用maxsum存储最大的分数,注意初值要赋一个较小值
void score_stat(int a[],int m)//传入一个数组,计算分数总和
{int max_score=0,min_score=10,sum=0;//最大分、最小分和分数总和for(int i=0;i<m;i++)//遍历数组{max_score=max(max_score,a[i]);//更新最大分min_score=min(min_score,a[i]);//更新最小分sum+=a[i];//更新分数总和}maxsum=max(maxsum,sum-max_score-min_score);//更新最大分数
}
int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)//循环n组数据{for(int j=0;j<m;j++)//循环读入一组数据scanf("%d",&s[j]);score_stat(s,m);}printf("%.2lf",double(maxsum)/(m-2));//输出答案return 0;
}

    注意:这里可以把数组作为参数传递进来。写法如上。当数组作为参数传递时,是直接传递进来的。比如上文的函数中的数组a就是函数外数组s的别名。改变数组a的值时数组s的值也会改变

4.递归函数

4.1.递归函数介绍

    函数可以被主函数和其他函数调用,也可以被自己调用。像这种自己调用自己的函数就叫做递归函数

4.2.例题3——计算阶乘

计算阶乘 - 洛谷

题目描述

n ! n! n!,也就是 1 × 2 × 3 ⋯ × n 1\times2\times3\dots\times n 1×2×3×n

挑战:尝试不使用循环语句(for、while)完成这个任务。

输入格式

第一行输入一个正整数 n n n

输出格式

输出一个正整数,表示 n ! n! n!

输入输出样例

输入 #1
3
输出 #1
6

提示

数据保证, 1 ≤ n ≤ 12 1 \leq n\le12 1n12

4.3.递归函数运行详细演示和代码

题意分析
    对于递归的题目,我们可以将这个问题拆分成多个子问题,并逐个解决。比如这个问题,我们可以把这个问题拆解成f(n)=n*f(n-1)其中f(n)代表n的阶乘。我们就可以得出程序:

#include<iostream>
using namespace std;
long long f(int n)//阶乘的数据较大,所以使用long long类型返回
{return n*f(n-1);
}
int main(){int n;cin>>n;cout<<f(n);return 0;
}

    但运行这个程序,我们会发现它结束不了。这是因为,当n=1时,f(n)应该返回1。但我们却没有加特殊判断。加上就可以通过这道题了。

#include<iostream>
using namespace std;
long long f(int n)//阶乘的数据较大,所以使用long long类型返回
{if(n==1)return 1;//递归边界return n*f(n-1);
}
int main(){int n;cin>>n;cout<<f(n);return 0;
}

像这种递归函数中递归终止的条件,就叫做递归边界

n=5时,递归函数f(n)的运行过程如下。
在这里插入图片描述
    如果看完这张图也不理解也没关系。随着学习的深入,你可能会在某一瞬间领悟。我就是这样子的。所以不用气馁,将一切都交给时间。

4.4.练习1——赦免战俘

赦免战俘 - 洛谷

题目背景

借助反作弊系统,一些在月赛有抄袭作弊行为的选手被抓出来了!

题目描述

现有 2 n × 2 n ( n ≤ 10 ) 2^n\times 2^n (n\le10) 2n×2n(n10) 名作弊者站成一个正方形方阵等候 kkksc03 的发落。kkksc03 决定赦免一些作弊者。他将正方形矩阵均分为 4 个更小的正方形矩阵,每个更小的矩阵的边长是原矩阵的一半。其中左上角那一个矩阵的所有作弊者都将得到赦免,剩下 3 个小矩阵中,每一个矩阵继续分为 4 个更小的矩阵,然后通过同样的方式赦免作弊者……直到矩阵无法再分下去为止。所有没有被赦免的作弊者都将被处以棕名处罚。

给出 n n n,请输出每名作弊者的命运,其中 0 代表被赦免,1 代表不被赦免。

输入格式

一个整数 n n n

输出格式

2 n × 2 n 2^n \times 2^n 2n×2n 的 01 矩阵,代表每个人是否被赦免。数字之间有一个空格。

输入输出样例

输入 #1
3
输出 #1
0 0 0 0 0 0 0 1
0 0 0 0 0 0 1 1
0 0 0 0 0 1 0 1
0 0 0 0 1 1 1 1
0 0 0 1 0 0 0 1
0 0 1 1 0 0 1 1
0 1 0 1 0 1 0 1
1 1 1 1 1 1 1 1

题意分析
    我们可以将这个方阵分成四个小方阵处理,我们先将这个方阵全部初始化为0。分别处理剩下的三个方阵递归边界为,处理到最后规模为1的方阵后就直接赋值为1。代码如下:

#include<iostream>
#include<cmath>
using namespace std;
#define MAXN 1030//2^10等于1024
int a[MAXN][MAXN],n,i,j;
/*cal是处理方阵的函数。x和y代表这个方阵的第一个人的坐标,n代表规模即代表这个方阵的大小是n*n的。*/
void cal(int x,int y,int n)
{if(n==0)//如果规模为0,即不可分割{a[x][y]=1;//赋值return;//返回}cal(x+pow(2,n-1),y,n-1);//处理右上角的方阵cal(x,y+pow(2,n-1),n-1);//处理左下角的方阵 cal(x+pow(2,n-1),y+pow(2,n-1),n-1);//处理右下角的方阵 
}
int main()
{cin>>n;cal(1,1,n);//从规模为n的方阵开始处理 for(i=1;i<=pow(2,n);i++)//打印方阵 {for(j=1;j<=pow(2,n);j++)cout<<a[i][j]<<' ';cout<<endl;}return 0;
}

5.基础宏函数

    还记得我们之前了解过的宏定义吗?既然它是简单粗暴的替换,那可不可以替换函数呢?当然可以。一个最基础的宏函数定义如下:

#define Add(a,b)return (a)+(b);

当然,我们也可以使用\宏定义转接符,这样就可以定义多行宏函数了。具体使用如下:

#define multiplication(a,b)cout<<a<<'*'<<b<<'='<<(a)*(b);\
return (a)*(b);

注意:在宏定义时一定要勤加括号,因为宏定义是直接简单粗暴的替换。可能会出现这种情况:

multiplication(1+2,3)

不加括号宏编译后就会变成这样。

1+2*3

不符合预期效果。所以要宏定义时要勤加括号。

6.课后作业

函数与结构体 - 洛谷 中函数部分

喜欢就订阅此专辑吧!

【蓝胖子编程教育简介】
蓝胖子编程教育,是一家面向青少年的编程教育平台。平台为全国青少年提供最专业的编程教育服务,包括提供最新最详细的编程相关资讯、最专业的竞赛指导、最合理的课程规划等。本平台利用趣味性和互动性强的教学方式,旨在激发孩子们对编程的兴趣,培养他们的逻辑思维能力和创造力,让孩子们在轻松愉快的氛围中掌握编程知识,为未来科技人才的培养奠定坚实基础。

欢迎扫码关注蓝胖子编程教育
在这里插入图片描述

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

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

相关文章

计算机基础(Windows 10+Office 2016)教程 —— 第6章 电子表格软件Excel 2016(下)

电子表格软件Excel 2016 6.4 Excel 2016的公式与函数6.4.1 公式的概念6.4.2 公式的使用6.4.3 单元格的引用6.4.4 函数的使用6.4.5 快速计算与自动求和 6.5 Excel 2016的数据管理6.5.1 数据排序6.5.2 数据筛选6.5.3 分类汇总6.5.4 分组显示6.5.5 合并计算 6.6 Excel 2016的图表6…

【RabbitMQ】通配符模式(Topics)

一、基本概念 生产者&#xff08;Producer&#xff09;&#xff1a;发送消息到RabbitMQ交换机的程序。生产者定义消息的路由键&#xff0c;用于标识消息的目的地。交换机&#xff08;Exchange&#xff09;&#xff1a;接收生产者发送的消息&#xff0c;并根据路由键和绑定规则…

一款.NET开源、跨平台的DASH/HLS/MSS下载工具

前言 今天大姚给大家分享一款.NET开源&#xff08;MIT License&#xff09;、免费、跨平台的DASH/HLS/MSS下载工具&#xff0c;并且支持点播和直播&#xff08;DASH/HLS&#xff09;的内容下载&#xff1a;N_m3u8DL-RE。 网络流媒体传输协议介绍 DASH DASH是一种基于HTTP的…

2024年8月1日(前端服务器的配置以及tomcat环境的配置)

[rootstatic ~]# cd eleme_web/ [rootstatic eleme_web]# cd src/ [rootstatic src]# ls views/ AboutView.vue HomeView.vue [rootstatic src]# vim views/HomeView.vue [rootstatic src]# nohup npm run serve nohup: 忽略输入并把输出追加到"nohup.out" 构建项目…

零基础入门转录组数据分析——机器学习算法之boruta(筛选特征基因)

零基础入门转录组数据分析——机器学习算法之boruta&#xff08;筛选特征基因&#xff09; 目录 零基础入门转录组数据分析——机器学习算法之boruta&#xff08;筛选特征基因&#xff09;1. boruta基础知识2. boruta&#xff08;Rstudio&#xff09;——代码实操2. 1 数据处理…

机器学习之贝叶斯方法

机器学习之贝叶斯方法 1. 贝叶斯定理基础1.1 贝叶斯定理公式1.2 先验概率 (Prior Probability)1.3 后验概率 (Posterior Probability)1.4 似然 (Likelihood)1.5 证据 (Evidence)1.6 贝叶斯定理的应用实例 2. 贝叶斯方法的基本概念2.1 条件概率 (Conditional Probability)2.2 全…

Python SDK 使用Azure Document intelligence报错(404) Resource not found

最近项目需要使用到Azure Document intelligence,于是去做POC&#xff0c;但是发现最简单的demo跑的时候都会报这个错&#xff0c;解决了一下午终于搞定了&#xff0c;记录下。 首先是官方文档&#xff1a;Quickstart: Document Intelligence (formerly Form Recognizer) clien…

反序列化漏洞vulhub靶场serial

环境搭建 下载 https://download.vulnhub.com/serial/serial.zip 解压出来就是这种 你会得到一个这样的文件&#xff0c;这里使用VMware新建一个虚拟机&#xff0c;这里记录比较重要的几部分。 这里就是使用我们刚才下过来的。 漏洞过程详解 1.信息收集 打开靶机&#xff0…

IDEA切换分支,会影响当前在跑的项目吗?

说明&#xff1a;本文测试&#xff0c;在IDEA中运行项目&#xff0c;然后切换分支&#xff0c;是否会影响当前正在跑的项目 准备工作 首先&#xff0c;创建一个Git项目&#xff0c;接口如下&#xff1a; import org.springframework.web.bind.annotation.GetMapping; import…

13. 文本框和单选题

属性说明type指定元素的类型。text、password、checkbox、radio、submit、reset、file、hidden、image和button&#xff0c;默认为textname指定表单元素的名称value元素的初始值。type为radio时必须指定一个值size指定表单元素的初识宽度&#xff0c;当type为text或password时&…

3.Java面试题之AQS

1. 写在前面 AQS&#xff08;AbstractQueuedSynchronizer&#xff09;是Java并发包&#xff08;java.util.concurrent&#xff09;中的一个抽象类&#xff0c;用于实现同步器&#xff08;如锁、信号量、栅栏等&#xff09;。AQS提供了一种基于FIFO队列的机制来管理线程的竞争和…

【RabbitMQ】路由模式(Routing)

一、基本概念 生产者&#xff08;Producer&#xff09;&#xff1a;发送消息到交换机的程序。在发送消息时&#xff0c;需要指定一个路由键。交换机&#xff08;Exchange&#xff09;&#xff1a;接收生产者发送的消息&#xff0c;并根据路由键将消息路由到与之匹配的队列。在…

1.kafka面试题之零拷贝

1. 写在前面 Kafka 是一个高性能的分布式消息系统&#xff0c;它使用了多种优化技术来提高数据传输效率&#xff0c;其中之一就是 “零拷贝”&#xff08;Zero Copy&#xff09;。零拷贝技术可以显著减少数据在内存中的复制次数&#xff0c;从而提高 I/O 操作的效率&#xff0…

volatile 关键字的两层语义

volatile 关键字的两层语义 1、可见性2、禁止指令重排序3、工作机制4、总结 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; volatile 关键字在Java并发编程中扮演着重要角色&#xff0c;它主要用于保证变量的可见性和禁止指令重排序。 1、…

python绘图 | 横坐标是日期,纵坐标是数值

需求 profit_value [0.084, 0.225, 0.234, 0.264, 0.328] time_stamp [20221111, 20230511, 20230704, 20231212, 20240315] 横坐标是日期&#xff0c;纵坐标是数值&#xff0c;我想绘图的时候&#xff0c;横坐标是按日期格式来 代码 from matplotlib import pyplot as pl…

Mallet:一款针对任意协议的安全拦截代理工具

关于Mallet Mallet是一款功能强大的协议安全分析工具&#xff0c;该工具支持针对任意协议创建用于安全审计的拦截代理&#xff0c;该工具本质上与我们所熟悉的拦截Web代理类似&#xff0c;只是通用性更强。 工具运行机制 Mallet建立在Netty框架之上&#xff0c;并且依赖于Net…

ThreadLocal:线程本地变量的作用与应用

ThreadLocal&#xff1a;线程本地变量的作用与应用 1、简介2、作用3、应用场景4、注意事项 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 1、简介 ThreadLocal 是Java中一个强大的工具类&#xff0c;用于创建线程局部变量。它为每个使用该…

7.Redis的Hash类型

Hash类型&#xff0c;也叫散列&#xff0c;其value是一个无序字典&#xff0c;类似于HashMap结构。 问题 String结构是将对象序列化为json字符串后存储&#xff0c;当需要修改对象某个字段是不是很方便。 key value…

AHK是让任何软件都支持 Shift + 鼠标滚轮 实现界面水平滚动

目录 基本介绍 详细特点 图解安装 下载失败&#xff1f;缓慢&#xff1f; 创建并运行脚本代码&#x1f603; 新建空 xxx.ahk文件 vscode/记事本等编辑工具打开 复制并粘贴简易脚本 运行 其他问题 问题一&#xff1a;弹出无法执行此脚本 关闭脚本 基本介绍 AutoHot…

大厂面试必备的软件测试八股文【附答案】

&#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 前言 最近有很多粉丝问我&#xff0c;有什么方法能够快速提升自己&#xff0c;通过阿里、腾讯、字节跳动、京东等互联网大厂的面试&#xff0c;我觉得短时间提升…