南哪 2022-5-function
大家好啊,这里是某 CQ !
这次是第一次准时推出的C-PL dotOJ补完计划!
其实这章题目还是挺水的,老师貌似是有选择性的听取了上次开会的提议,让OJ的前几题较为简单,便于练习。
这章主要是要求我们通过函数将代码分块,各个函数解决小范围内的一些问题,然后将它们组合起来解决整个问题。
如果你并没有学习函数并能灵活使用,那么这次的OJ作业对你来说仍然十分煎熬磨人。
那么,函数究竟是干嘛用的呢?
来看下面一个例子:
int n;
int cycle(int x) {
if (x > n) {
x -= n;
}
if (x < 1) {
x += n;
}
return x;
}
int main() {
while (1) {
x = cycle(x + 1);
}
return 0;
}
(这代码当然是个死循环,不要想着去运行)
(某 CQ 将这个函数用在了约瑟夫问题当中,他发现这玩意真的很好用。)
通过写这样一个 cycle
函数,我们将 x
的值成功的限制在了 1 到 n 的范围内,使得 x
可以在某一范围内循环地往右运动。
你实际上可以发现函数只不过是把一些东西放到另一个地方去写罢了。这有什么用呢?
非也!当你在很多地方都要做同一种操作,你就堆在主函数里面?那自然写出来的代码是十分臃肿的。
想想不久前你可能仍然挣扎在数百行代码之中,但你会发现你实际上大部分的代码都是在复制粘贴。
如果有一种代码能够统一的表示这些操作,那该多好啊?
这就是函数的用途所在,把一些繁复的语句打包,在你想用的时候,说一声就完事了。
我们来分析一下函数的定义方法:
首先,函数是不能定义在某一个函数里面的,我们一直在写的 int main()
就是一个特殊的函数。
提示
main
作为 C 语言规定的程序的入口,所有的程序都从这里开始执行,因此,每一个 C 语言程序都必须包含 main
函数
我们以上面的 cycle
函数为例,来解释一下函数的结构:
首先是这个函数的返回值类型:我们在 cycle
函数中需要获得 x
限制在 1 到 n 范围内的值,所以它的返回值肯定是我们想要得到的那个值,也就是一个 int
值。
然后是这个函数的名字,这个不必说,函数后面一定有括号,括号中可以填一些传入该函数的参数,说人话,就是告诉函数它需要知道这些值,它才能给你算出答案来。在 cycle
函数中我们传入了经过处理的 x
值,希望通过函数将它限制在 1 到 n 的范围内。
另外,如果你想要传入多个参数,你必须用逗号隔开并分别指定每一个变量的类型,即使变量类型是一样的也不行。
最后是这个函数的主体部分,具体怎么实现自然不必说,大家应该都会。
特别的,函数有一种特别的类型,叫做 void
函数,void
函数没有返回值,而仅仅是作为一个操作存在,在主函数中可以直接调用这个函数来实现这个操作。
这也是某 CQ 一直想让你们把关键的变量放在主函数外面的原因。当你将函数定义在这些变量后面的时候,因为这些变量已经声明,在函数中没有变量与之重名的情况下(注意!这个非常的重要!),你可以调用和修改这些变量!
举一个 void
函数的例子:
int a[10005];
void reverse(int l, int r) {
while (l < r) {
int t = a[l];
a[l] = a[r];
a[r] = t;
++l, --r;
}
}
通过这样一个函数,我们便实现了一个简单的操作:将数组从 l 到 r 这个区间反转。
(这也正是某 CQ 在这周的 E 题 下一个排列中用到的函数)
在函数的使用过程中,我们需要特别注意这一点:
当一个函数有了返回值,这个函数就会直接结束。
比如说大家可能已经尝试通过在主函数里直接 return 0;
来提前结束主函数,这也是一个优化的小技巧,当你的函数已经得出结论,没必要继续下去的时候,你能直接通过返回值来立即离开这个已经没有用的函数。
可能你想问,void
函数也能返回值吗?
当然可以啊,void
只要返回空的不就行了嘛,也就是说,在 void
函数中,你也可以使用 return;
来直接退出。
这样就大致讲解了函数的使用方法。
还不明白?来告诉你们一个使用实例:
本周作业 D 题,也就是确定进制那道题,你可以编写一个判断是否确认符合进制规则的函数,再编写一个将 n 进制的数转化为 10 进制的数的函数,然后判断p,q,r是否在某一个进制下符合条件?只需要在这三个数都符合条件的情况下,转化为十进制的 p 和 q 的乘积等于十进制下的 r 就行了哦
是不是感觉比不用函数的思路简单许多?
(某 CQ 表示函数真的很好用,大家一定要多加练习)
这次的题单也许会出现之前题单中出现的题目,某 CQ 这次希望大家使用函数的方法来解决这些题目。
感谢各位的收看!
题单链接: