Skip to content

函数

本节有对应的视频教程,请到Rbook的仓库查找

什么是函数: 带有名字的代码块 出现的原因:

  1. 复用
  2. 递归

使用函数的好处:

  1. 模块化
  2. 易读
  3. 易修改(只用修改对应的函数)

定义

什么是函数:通常,一个函数即能完成某一特定操作,又能计算数值。

函数定义的语法方式

plaintext
[返回值类型] [函数名字](参数列表) {
    函数体
}
1
2
3

返回值类型 : void int double char bool

返回值语句: return

return 应该如何使用?

  • 如果函数是void类型 那么应该这样写return;
  • 如果函数是int类型 return 数值/表达
  • 其它类似

注意:函数遇到return,函数就结束了

例子

输出100行******.

c
#include <cstdio>
void print_star(){
    printf("******\n");
}
int main(){
    int i;
    for(i=1;i<=100;i++)
        print_star();
    return 0;
}
1
2
3
4
5
6
7
8
9
10

有关函数的说明

  • 函数的数据类型就是函数的返回值类型(如果没有返回会,使用void 类型)
  • 函数名是标识符,按标识符的写法书写.
  • 形式参数列表可以为空(无参函数).
  • 不可以在函数的内部定义一个函数
  • 一个程序必须有且只有一个main( )函数,C++从main( )函数开始执行。

使用函数的好处

  1. 避免重复的编程。
  2. 使程序更加模块化,便于阅读、修改。

无参函数

  • 主调函数并不将数据传给被调函数。
  • 无参函数主要用于完成某一操作。
数据类型 函数名(形式参数列表){
    函数体
}
1
2
3

例子

[题目]读入n个数字,如果输入的数字是1,就输出:

*
**
***
1
2
3

[样例输入]:

3
1 2 1
1
2

[样例输出]:

*
**
***
*
**
***
1
2
3
4
5
6

[代码]

c
#include <cstdio>

void print_start(){
    printf("*\n");
    printf("**\n");
    printf("***\n");
}
int main(){
    int n,i;
    scanf("%d",&n);
    for(i=1;i<=n;i++){
        int t;
        scanf("%d",&t);
        if( t == 1)
            print_start();
    }
    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

有参函数

例子

[题目]读入n个数字,根据输入的数字,输出底层长度为输入数字大小的金字塔,如果读入的数字是3,则输出如下:

*
**
***
1
2
3

[样例输入]:

3
1 2 1
1
2

[样例输出]:

*
*
**
*
1
2
3
4

[代码]

c
#include <cstdio>
void print_star(int n){
    int i,j;
    for(i=1;i<=n;i++){
        for(j=1;j<=i;j++){
            printf("*");
        }
        printf("\n");
    }
}
int main(){
    int i,n;
    scanf("%d",&n);
    for(i=1;i<=n;i++){
        int t;
        scanf("%d",&t);
        print_star(t);
    }
    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

函数的返回值

  • return 会把值返回给主调函数
  • 函数执行到return语句的时候,直接退出,即使后面还有语句没有执行.
  • 当一个函数没有返回值的时候,函数可以没有return语句时.函数执行到函数体的右花括号}时结束.
return 表达式;
1

void类型 的返回写法.

return ;
1

怎么样理解函数:把它当成高中函数数学中的函数f(x),接收参数,返回运算结果.

样例题目

输入两个数字,输出两者的最大值.

代码

c
#include <cstdio>

int max(int a,int b){
    int m =a;
    if( a < b)
        m = b;
    return m;
}

int main(){
    int x,y;
    scanf("%d%d",&x,&y);
    int m = max(x,y);
    printf("%d",m);
    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

全局变量与局部变量

局部变量: 定义在函数内部的变量称为局部变量(Local Variable),它的作用域仅限于函数内部, 离开该函数后就是无效的,再使用就会报错。

c
#include <cstdio>
void _my_(int x){
    int a=5;//属于_my_函数的局部变量
    printf("%d\n",a);//输出5
}
int main(){
    int a = 10; //属于main函数的局部变量
    _my_(100);//调用函数
    printf("%d\n",a);//输出10
    return 0;
}
1
2
3
4
5
6
7
8
9
10
11

全局变量:在所有函数外部定义的变量称为全局变量(Global Variable),它的作用域默认是整个程序

c
#include <cstdio>
int a; //全局变量,所有函数都可以看到,操作它
void _my_(int x){
    a=5;
    printf("%d\n",a);//输出5
}
int main(){
    a = 10; //属于main函数的局部变量
    printf("%d\n",a);//输出10
    _my_(100);//调用函数
    printf("%d\n",a);//输出5
    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13

思考下面的代码的输出是什么:

c
#include <cstdio>
int a; //全局变量,所有函数都可以看到,操作它
void _my_(int x){
    int a=5;
    printf("%d\n",a);//输出5
}
int main(){
    a = 10; //属于main函数的局部变量
    printf("%d\n",a);//输出10
    _my_(100);//调用函数
    printf("%d\n",a);//输出10
    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13

输出是:

10
5
10
1
2
3

我们可以看到_my_函数没有改变全局变量a的值,那是因为它自己有一个变量也叫a,当一个函数要操作一个变量的时候,它先找自己的局部变量,如果找不到,再去找全局变量,但不会找其它函数的局部变量


【注意】:

    1. 在 main 函数中定义的变量也是局部变量,只能在 main 函数中使用;同时,main 函数中也不能使用其它函数中定义的变量。main 函数也是一个函数,与其它函数地位平等。
    1. 形参变量、在函数体内定义的变量都是局部变量。实参给形参传值的过程也就是给局部变量赋值的过程。
    1. 可以在不同的函数中使用相同的变量名,它们表示不同的数据,分配不同的内存,互不干扰,也不会发生混淆。
    1. 在语句块中也可定义变量,它的作用域只限于当前语句块

【示例】根据长方体的长宽高求它的体积以及三个面的面积。

c
#include <stdio.h>

int s1, s2, s3;  //面积

int vs(int a, int b, int c){
    int v;  //体积
    v = a * b * c;
    s1 = a * b;
    s2 = b * c;
    s3 = a * c;
    return v;
}

int main(){
    int v, length, width, height;
    printf("Input length, width and height: ");
    scanf("%d %d %d", &length, &width, &height);
    v = vs(length, width, height);
    printf("v=%d, s1=%d, s2=%d, s3=%d\n", v, s1, s2, s3);
    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

运行结果:

Input length, width and height: 10 20 30↙
v=6000, s1=200, s2=600, s3=300
1
2

函数调用的参数传递

函数调用原则

函数调用遵循先定义、后调用的原则,即被调函数应出现在主调函数之前。

c
#include <cstdio>

void _you_(int x){ //这里会出错,因为在前面看不到_my_
    _my_(x);
}

void _my_(int x){
    int a=10;
}

int main(){
    _you_(5);
    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

函数的参数传递

调用的一个函数的过程具体是怎么样的?参数又是怎么传递的呢?

c
#include <cstdio>

int add(int a,int b){
  int c = a+b;
  return c;
}

int main(){
    int a = 1;
    int b =2;
    int c = add(a,b);
    printf("%d",c);
    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

在上面的代码中,函数add的参数int a,int b本质是属于add的局部变量,只不过做为参数接收数值而已.

具体的过程演示:函数的参传递

看完上面的演示之后,得出:函数在传递参数的过程中传递的是变量的值,而不是变量本身

Return 语句

在函数运行的过程种,只要遇到retrun语句,就会直接退出(返回)当前函数,返回到调用这个函数的函数处的下一行.

作业

openjudge函数部分 http://noi.openjudge.cn/ch0112/

问题1 求最大值

  • 第一行,一个整数n,表示要求接下来n行一对整数的最大值
  • 第n+1行,一个整数m,表示要求接下来m行三个整数的最大值
plaintext
3
1 2
3 1
2 3
3
1 2 3
3 2 1
1 4 7
1
2
3
4
5
6
7
8

不使用函数

cpp
#include <iostream>
using namespace std;

int main(){
    int n,m;
    std::cin >> n;
    for(int i=1;i<=n;++i){
        int a,b;
        std::cin >> a >> b;
        if( a > b ) 
            std::cout << a << std::endl;
        else
            std::cout << b << std::endl;
    }
    std::cin >> m;
    for(int i=1;i<=m;++i){
        int a,b,c;
        std::cin >> a >> b >> c;
        if( a < b)  a = b; //a是 a b 之间的最大值
        if( a < c ) a = c;//a是 a c 之间的最大值
        std::cout << a << std::endl;
    }
    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
cpp
#include <iostream>
using namespace std;

int mymax(int a,int b){
    if( a > b) return a;
    return b;
}

int main(){
    int n,m;
    std::cin >> n;
    for(int i=1;i<=n;++i){
        int a,b;
        std::cin >> a >> b;
        std::cout << mymax(a, b) <<endl;
    }
    for(int i=1;i<=m;++i){
        int a,b,c;
        std::cin >> a >> b >> c;
        std::cout << mymax(mymax(a, b),c) << std::endl;
    }
    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

发现使用了函数后,代码量变少了,可读性变高了.