当前课程知识点:程序设计基础 > 第四章 筛法与查找 > 4.1 插花游戏 > 4.1.2 函数初探
好我们接着上一节的内容
我们上一节最后是要找一个数学函数来判断
一个整数N是不是素数
那根据我们第一章答疑的过程当中曾经提到过
查找一个数学函数的方法
有可能利用以前已知的数学函数进行推导
要么我可以上网去查一下有没有类似的函数
那同学们可以自己去试一下
很可惜我们最后上网查没有
我们需要的判断素数的数学函数
那我们这个程序都已经写成这样了
很完整了
能不能自己写一个这样的函数
以后也可以自己进行使用
解决更复杂的有关于判断素数的问题呢
答案是肯定的
那关键的一个概念就是
我们要引入一个
自己定义的函数这样一个概念
那函数这个概念其实也没有
一个特别标准的定义
我们这里对它进行自己理解上的一个定义
函数的英文叫function
我们认为它是一个具有特定功能的
而且相对独立的模块
能够被程序多次的使用
如果满足这样的性质
我们一般会把它设计成一个函数
那么其中有标红的这几个字
功能 模块 多次使用
我们根据这三个关键词依次会有
函数设计当中的三个要素跟它对应
分别是定义、声明和调用
那我们就先来看看声明
声明其实很简单
就是一行 bool isPrime(int);
这一行表达的意思是我向计算机宣称
有这样一个函数 名字叫isPrime
它括号里有一个int类型的输入
名字前面的bool表达的是它有一个输出
是bool类型的输出
我们最后希望它的功能是括号里面的int
判断它是不是素数 作为输出返回回来
有了这个函数的声明之后
我们就可以进行函数的调用了
我们看看怎么通过函数调用
我们把程序进行一些改写
这是我们刚才的程序
其实特别简单
就把我们刚才写出来的这个程序当中的??
把刚才我们自己定义的声明的函数名添上
isPrime添在里面
这个程序就结束了 就写成了
那甚至于说跟我们其它的数学函数一样
我们的数学函数sin、cos这种
不一定运算结果非要拿一个变量来存它
我们可以直接把它进行运算
那同样的如果我这个函数的
运行结果是一个布尔值
我可以直接让它去参与if的判断
可以把它写在if判断的括号里面
写在括号里面它就是表达式的一部分了
不需要写最后那个分号了
它不再是一个初始化语句
或者是一个赋值语句了
那写成这样之后我们一看
是挺简洁的 也确实写完了
那看看我们确实使用了函数之后
写程序方便了很多
有同学会感觉是不是有点不太对劲
感觉少了点什么 这个没关系
咱们先把这样一个程序写到编辑器当中试试看
下面我们把声明和调用的过程写到编辑器当中
选择菜单中的编译选项
这时候我们会发现它提示了一个红色的错误
Id returned 1 exit status
那么为什么会出现这么一个错误呢
那我们下面就来看一下这个函数的定义
写成这边这个样子
第一个函数的定义我就直接写给大家了
其中有几个关键的要素
红色的部分我们叫函数的名称
跟刚才声明的时候是一样的
蓝色的部分是函数的参数
这里面除了声明的时候的类型
后面加了一个n
表示的是这个参数的名称是一个n
那看我下面这个函数定义的实体里面
一对大括号中间其实就用到了n这个变量
就把它当成了输入的这个变量
绿色的这个部分是函数的返回值
除了跟声明一样前面有一个bool类型的
表达我的返回值是bool类型之外
一旦有返回值 我的函数体的大括号中间
最后面有一个return这样一个语句
表达我返回的一个数值
这里我要么就返回一个true
要么返回一个false
中间这段函数
内容就是判断一个数是不是素数
就是输入的那个整数n是不是素数
如果是 最后运算的结果就会
把bPrime等于true返回回去
否则就会把bPrime是false返回回去
这个具体的逻辑我就不详细讲了
大家可以自己去详细的看一下
那有了这样一个函数的定义
我们是不是仔细看一下这个大概的架构
有没有感觉很熟悉
有同学发现了像我们函数这样一个定义的架构
跟我们写了很多次的main函数是长得差不多的
同样就是main函数前面有一个int
然后一个大括号
大括号最后需要有一个return
return的内容反正是一个int类型的
一般我们都写成return是0
确实我们自定义的函数就是
跟我们平常定义的main函数本质上是一样的
所以我们就参考我们以前
写main函数的经验去实现一些
自己定义的函数就可以了
那回过头来我们把刚才的函数定义
也加到我们刚才写的这个程序当中
从刚才的程序
我们把刚才这个定义也拷到程序当中来
我们第一次把它拷到main函数的后面
编译 发现它能够编译成功
那么这个定义的位置其实是可以任意的
我们可以把它拷贝到main函数的前面
同样也是能够编译成功
而且如果我们写在了main函数的前面
可以把声明的过程删掉
也是一个合法的写法
但是如果我们一旦不写这个声明
那么定义就一定要在调用之前
也就是我们现在这个样子
要写在main函数前面
写成这样一个函数之后
这样一段程序之后
我们来看一看程序的执行的过程
实际上我们在主函数当中
这个循环每一次执行到isPrime(n)
的时候都会进行以下的几个步骤
首先它会把main函数当中的n
循环变量赋值给isPrime函数当中的参数
我们这里把这个参数也起名为
int这个变量起名为n
其实可以换成别的 只要在int
isPrime这个函数里面保持一致就可以了
赋值之后去执行isPrime的函数定义
当中的这个过程就好像
执行main函数的定义过程一样
在isPrime函数里面的内容执行完之后
会把isPrime函数的返回值
拿回到主函数当中参与if的判断
回到原来调用的位置继续执行
如果下一次循环n=2之后
然后n=3的时候还会再进行一遍这样的步骤
如果同学们把它展开我们会发现
其实就跟我们没有写函数
把这个刚才函数当中的定义的内容
直接抄到循环当中是一样的
那我们为什么还写这么一个函数
直接抄不就得了么 抄过来就行了
那有几个关键的点 一个呢
这个问题当中我们只调用了
一次isPrime这个函数
如果说我们这个问题比较复杂
经常需要判断isPrime
就是一个整数是不是素数
那我一旦写了这个函数之后
我就可以把它调用多次 写多次
另外一个 我们这个isPrime这个函数
由于把它写成一个函数
还可以进行一定的简化
比如说 我们再看一下这个定义
其中有一句bPrime=false
然后就break跳出循环
那我们会发现跳出循环之后
就直接走到了return bPrime这一句
函数返回的过程
实际上如果是从break出来的
它return的就一定是false的值
所以我们可以把赋值等于false
然后break这句话改成return false
也就是说同一个函数之内
其实可以有两条return的语句
在你需要返回的时候就
直接从那个地方返回就可以了
那么相应的下面循环外面的这个return
bPrime那么肯定就会返回true这个值
所以我们可以把它改成return true
那如果我们把这两条都改掉了
就发现变量bPrime实际上没有用了
就可以把它删掉
都删掉之后我们会发现if里面只有一条语句
for里面也只有一个if语句
那么我们也可以把大括号对应的删掉
通过这些修改 一看我们判断素数的过程
实际上就四行代码就可以解决的
是不是变得很简洁
所以总结一下我们刚才自定义函数的过程
除了我们需要有定义
然后我们去调用它自己定义的这个函数
一方面可以使我们程序设计的思路更加清晰
我们不用去管isPrime
里面到底是怎么实现的
我们可以假设我们有这样一个功能
然后就去调用它完成我们主函数的功能
当我们出现了一些链接错误的时候
大概我们就可以发现
应该是我们有些函数声明了
或者是宣布我们应该有这样一个函数
但是计算机没有找到这个函数的功能
这个函数的的定义 才会发生这个链接错误
那当这个时候我们再去实现isPrime函数
再去定义它 也是可以的
而且在函数定义的时候
有时候会有一些简化的写法
可以在程序的执行当中直接return
在主函数当中我们直接return
这个程序就退出了
有的时候我们不希望这种
但是在函数里直接return就可以很快的跳出
那下一段我们会把这样一个程序
运行来看一下它的效果
-1.1 基础知识
-1.2 买菜问题
-1.3 数学运算
-1.4 补充说明
-1.5 总结
--1.5 总结
-程设论道
--程设论道
-师生问答
-第一章 编程初步--语法自测
-2.1 关于超级计算器的几点思考
-2.2 电子秤模拟 — 背景介绍及需求分析
-2.3 电子秤模拟 — 代码实现
-2.4 变量定义与变量类型
-2.5 猜数游戏与数据表示
-2.6 关于变量的讨论
--公告
-2.7 变量体现的计算思维
-程设论道
--程设论道
-师生问答
--师生问答
-第二章 变量与代数思维--语法自测
-3.1 谁做的好事——语义表示
-3.2 谁做的好事——真假检查
-3.3 谁做的好事——循环枚举
-3.4 谁是嫌疑犯——多重循环枚举
-3.5 谁是嫌疑犯——破案线索表示
-3.6 谁是嫌疑犯——用二进制枚举
-程设论道
--程设论道一
--程设论道二
--程设论道三
-师生问答
-第三章 逻辑推理与枚举解题--语法自测
-4.1 插花游戏
-4.2 筛法
-4.3 线性查找
-4.4 折半查找
--4.4.1 提问
-4.5 排序问题
-4.6 总结
--4.6.1 总结
-程设论道
--程设论道二:筛法
-师生问答
-第四章 筛法与查找--语法自测
-5.1 阶乘
-5.2 排序
-5.3 矩阵填充
-5.4 分书与八皇后
-5.5 青蛙过河
-程设论道
--程设论道一
--程设论道二
-师生问答
--师生问答一
--师生问答二
-第五章 分治思想与递归--语法自测
-6.1 兔子数列问题
-6.2 分鱼问题
-6.3 橱窗的插花问题
-6.4 最长公共子序列问题
-程设论道
--程设论道一
--程设论道二
-师生问答
--师生问答
-第六章 递推与动态规划--语法自测
-7.1 统计记录总数
-7.2 统计活跃用户数
-7.3 统计在线时长
--7.3.2 结构
-7.4 总结
--7.4.1 总结
-程设论道
--程设论道
-师生问答
--师生问答
-第七章 文本数据处理--语法自测
-8.1 将数据组织成链表
-8.2 提高链表访问效率 —— 哈希链表
-8.3 以二进制文件存储链表
-程设论道
--程设论道一
--程设论道二
-师生问答
--师生问答
-第八章 非文本数据处理--语法自测
-9.1 自动售卖程序
-9.2 配制水果信息
-9.3 指定界面语言
-程设论道
--程设论道
-师生问答
--师生问答
-第九章 可配置的程序设计--语法自测