美文网首页NOIP之路
【语法篇】13、函数

【语法篇】13、函数

作者: 沧海无雨 | 来源:发表于2017-02-22 11:26 被阅读18次

一、函数是什么

我们从函数的产生来看,其实很好理解,因为某些代码或运算需要反复使用,作为一名志向远大(懒癌后期)的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官网题库。

相关文章

  • 【语法篇】13、函数

    一、函数是什么 我们从函数的产生来看,其实很好理解,因为某些代码或运算需要反复使用,作为一名志向远大(懒癌后期)的...

  • 第六篇. 函数

    第七篇. Excel函数 一、IF函数 (一)IF函数的基本用法 函数语法:IF(logical_test,[va...

  • swift学习笔记②

    Swift学习笔记 - 文集 语法篇 一、函数 函数定义 Swift 定义函数使用关键字 func,functio...

  • Python语法 - 函数篇

    函数是函数式编程语言的魅力所在。这一章节,我们就来了解下Python的函数 什么是函数 函数是组织好的,可重复使用...

  • shell编程之函数

    1.函数的定义和语法 函数由两部分组成:函数名和函数体 语法一: 语法二: 语法三: 2.函数调用 调用:函数只有...

  • 第五篇:Kotlin之函数和Lambda表达式

    上篇:第四篇:Kotlin之数组和集合 在使用函数之前必须先定义函数。定义函数的语法格式如下: fun 函数名(形...

  • 函数周期表丨时间丨值丨WEEKDAY&WEEKNUM

    WEEKDAY函数与WEEKNUM函数 WEEKDAY语法: WEEKNUM语法: WEEKDAY函数与WEEKN...

  • 三篇文章带你快速入门 Kotlin(下)

    三篇文章带你快速入门 Kotlin(下) infix函数 我们前面介绍mapOf函数,A to B 这样的语法结构...

  • Golang学习笔记-1.6 函数

    本文系第六篇Golang语言学习教程 声明函数 语法 函数声明包括:函数名name:自定义的函数名形式参数列表()...

  • 单行函数

    一、SQL函数概述 SQL函数分类 单行函数多行函数 单行函数语法 语法:函数名[(参数1,参数2,….)]注意:...

网友评论

    本文标题:【语法篇】13、函数

    本文链接:https://www.haomeiwen.com/subject/aoppwttx.html