【语法篇】13、函数

一、函数是什么

我们从函数的产生来看,其实很好理解,因为某些代码或运算需要反复使用,作为一名志向远大(懒癌后期)的OIer,我们往往不想反反复复地写同样的代码(有些可能要改一些数据),所以我们想要有一个“东西”来专门实现我们的运算,我们期待只需要写一遍代码,以后要使用的时候,直接调出来就可以,这个“东西”,在C++和很多语言中,都叫做函数。因为很多时候需要改动一些数据,我们在调用的时候也往往要带上这写改动的数据,这些数据就是我们函数中的参数了,当然也有一些函数根本就不用改数据,也可以不带参数。

举个例子说明一下:

我们要求:1!+2!+3!+4!+5!+6!+...+20!=?

很显然,用前面的知识,我们可以轻易地用两重循环来实现求和。


int sum=0;

for(int i=1; i<=20; i++){

  int jc=1;

 for(int j=1; j<=i; j++)

  jc*=i;

sum+=jc;

}
// sum即是结果

但有时,我们又会觉得它并不是特别方便,因为有时我们求阶乘的时候,不一定是像现在这么规律,从1到n的阶乘,譬如:
求:3!+10!+13!=?
我们总不希望把阶乘这样一个过程重复地写几遍吧。这时候,我们不妨换一个思路来看,在前面的经验中,我们已经使用过cmath库中的sqrt(),其实这就是一个数学库的函数,既然有开平方的函数,那有没有一个阶乘的函数呢?我们暂且假设有阶乘的函数,并且设它为jc(),那么我们可以这样来实现。

#include <iostream>
#include <cmath>
using namespace std;
  int main(){
  int sum=0;
  sum+=jc(3);
  sum+=jc(10);
  sum+=jc(13);
  cout<<sum<<endl;
  return 0;
}

但是遗憾的是,在数学库中,并没有这样一个函数。一般库函数中都是包含了最基础、最常用的函数,在数学库的设计者眼中和实践中,阶乘并不算特别常用的函数,因此并没有收录到数学库中。但是也没有关系,我们完全可以自己定义一个函数,譬如就定义为jc(),那么我们的程序就可以这样写了。

#include <iostream>
using namespace std;
// 注意:这是jc的函数
int jc(int x){ 
  int t=1;
  for(int i=1; i<=x; i++)
    t*=i;
  return t;//返回结果
}  //函数结束

  int main(){
  int sum=0;
  sum+=jc(3);
  sum+=jc(10);
  sum+=jc(13);
  cout<<sum<<endl;
  return 0;
}

总结一下,其实函数很简单,就是我们不希望重复写代码,所以想借助函数来减少重复代码,通过函数来实现某个动能。同时我们留意到,函数实现某些功能或计算,很多时候会带入一些数据,也就是参数,很多时候还需要得到一个结果,也就是返回值的问题。


二、函数在程序中的结构和调用关系

函数定义,参照书本知识,举个例子说明函数的结构和使用方法。(要求实现最简单的加法功能)

#include <iostream>
using namespace std;

int main(){
  int a, b;
  cin>>a>>b;
  int c=add(a, b);
  cout<<c;
  reuturn 0;
}

我们在写简单程序时(区别于工程型编程),往往会先写函数的主体结构和框架,然后在去填充具体的功能,表现在编程中,其实就是先写主程序main,然后要实现什么功能,先假设有一个函数,可以实现那个功能,一路写下来。然后再去完善具体的功能,最后需要测试数据和考虑各种可能的bug。
函数写法,有两种,一种是写在主程序前,不要事先声明;一种是写在主程序后,但是要在主程序前声明函数。在这里,基于OI或ACM类型的比赛,建议大家把函数都写在main前面,并且越先使用的函数写在最上面,可以减少没必要的函数声明和定义。像上面的一个案例,假如我们要实现一个加法的功能,我们可以这样写。
在写的时候,我们就要考虑几个问题:

1、函数需要返回值吗?什么类型?
2、需要参数吗?几个参数?分别什么类型?
3、需要改变本身传递的数据吗?即是考虑“传值”还是“传址”,还有全局变量与局部变量的考虑。
4、测试bug,特殊值

参照上面几个问题,我们逐个考虑:要得出相加的结果,显然需要返回值,而且应该是int类型;参数的话,因为是两个数相加,因此两个加数就是参数,类型也是int;我们只是需要得到一个计算的结果,并需要去改变两个加数的原始数字,因此考虑"传值",不涉及全局数据,局部变量即可;特殊值考虑负数、零等的相加。
完整代码如下:

#include <iostream>
using namespace std;

int add(int x, int y){
  return (x+y);  //建议加上括号
} 

int main(){
  int a,b;
  cin>>a>>b;
  int c=add(a, b);
  cout<<c;
  return 0;
}

需要说明的是,main()本身就是函数,并且是主函数,所有程序都必须用main开始,并且遵循顺序结构的规则。那么涉及到函数的各种调用的时候,我们需要稍微加以理解。从main开始,从上往下,从左往右,执行,遇到函数f1,就跳转到函数f1处执行,直到遇到f1中的return语句或f1函数结束,才重新回到之前调用的地方。打个比方:我们来到学校上课,都是按照一定顺序进行的,每次都是先过周一、周二、周三...一直到放学。那么函数的引入,就像是我们在周二晚上,我们做了一个梦,梦见我们要去做一些事情,做完梦之后,我们又重新回到做梦的那个时间点,也就是回到周二,再过周三,一直下去。有点意思的是,梦里可能还会再有梦,实际上,这就是在函数中再调用函数的意思,如果梦里继续做了同样的梦,那就是所谓的递归了。

基础练习

1、求两个正整数的最大公约数(辗转相除法)
2、进制的转换(a.由十进制转二进制,b.由二进制转十进制,c.m进制转n进制)
3、更多练习,参见函数过关题和NOI官网题库。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,117评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,963评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,897评论 0 240
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,805评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,208评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,535评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,797评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,493评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,215评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,477评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,988评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,325评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,971评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,807评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,544评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,455评论 2 266

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,563评论 25 707
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,097评论 18 139
  • [TestFixture(arguments)]属性标记类为测试类,若没有填写参数,则测试类必须含有无参构造函数,...
    皿卜土阅读 554评论 0 0
  • 碰见三观不同的人犹如秀才遇到兵,有理说不清。话不投机半句多,永远无法在一个频率上,鸡同鸭讲。虽近在咫尺,然远在天边...
    闵语兰心阅读 689评论 6 7