函数
本节有对应的视频教程,请到Rbook的仓库查找
什么是函数: 带有名字的代码块 出现的原因:
- 复用
- 递归
使用函数的好处:
- 模块化
- 易读
- 易修改(只用修改对应的函数)
定义
什么是函数:通常,一个函数即能完成某一特定操作,又能计算数值。
函数定义的语法方式
[返回值类型] [函数名字](参数列表) {
函数体
}
2
3
返回值类型 : void int double char bool
返回值语句: return
return 应该如何使用?
- 如果函数是void类型 那么应该这样写
return;
- 如果函数是int类型
return 数值/表达
- 其它类似
注意:函数遇到return,函数就结束了
例子
输出100行******
.
#include <cstdio>
void print_star(){
printf("******\n");
}
int main(){
int i;
for(i=1;i<=100;i++)
print_star();
return 0;
}
2
3
4
5
6
7
8
9
10
有关函数的说明
- 函数的数据类型就是函数的返回值类型(如果没有返回会,使用void 类型)
- 函数名是标识符,按标识符的写法书写.
- 形式参数列表可以为空(无参函数).
- 不可以在函数的内部定义一个函数
- 一个程序必须有且只有一个main( )函数,C++从main( )函数开始执行。
使用函数的好处
- 避免重复的编程。
- 使程序更加模块化,便于阅读、修改。
无参函数
- 主调函数并不将数据传给被调函数。
- 无参函数主要用于完成某一操作。
数据类型 函数名(形式参数列表){
函数体
}
2
3
例子
[题目]读入n个数字,如果输入的数字是1,就输出:
*
**
***
2
3
[样例输入]:
3
1 2 1
2
[样例输出]:
*
**
***
*
**
***
2
3
4
5
6
[代码]
#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;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
有参函数
例子
[题目]读入n个数字,根据输入的数字,输出底层长度为输入数字大小的金字塔,如果读入的数字是3,则输出如下:
*
**
***
2
3
[样例输入]:
3
1 2 1
2
[样例输出]:
*
*
**
*
2
3
4
[代码]
#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;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
函数的返回值
return
会把值返回给主调函数- 函数执行到
return
语句的时候,直接退出,即使后面还有语句没有执行. - 当一个函数没有返回值的时候,函数可以没有
return
语句时.函数执行到函数体的右花括号}
时结束.
return 表达式;
void
类型 的返回写法.
return ;
怎么样理解函数:把它当成高中函数数学中的函数f(x)
,接收参数,返回运算结果.
样例题目
输入两个数字,输出两者的最大值.
代码
#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;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
全局变量与局部变量
局部变量: 定义在函数内部的变量称为局部变量(Local Variable),它的作用域仅限于函数内部, 离开该函数后就是无效的,再使用就会报错。
#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;
}
2
3
4
5
6
7
8
9
10
11
全局变量:在所有函数外部定义的变量称为全局变量(Global Variable),它的作用域默认是整个程序
#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;
}
2
3
4
5
6
7
8
9
10
11
12
13
思考下面的代码的输出是什么:
#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;
}
2
3
4
5
6
7
8
9
10
11
12
13
输出是:
10
5
10
2
3
我们可以看到_my_
函数没有改变全局变量a
的值,那是因为它自己有一个变量也叫a
,当一个函数要操作一个变量的时候,它先找自己的局部变量,如果找不到,再去找全局变量,但不会找其它函数的局部变量
【注意】:
- 在 main 函数中定义的变量也是局部变量,只能在 main 函数中使用;同时,main 函数中也不能使用其它函数中定义的变量。main 函数也是一个函数,与其它函数地位平等。
- 形参变量、在函数体内定义的变量都是局部变量。实参给形参传值的过程也就是给局部变量赋值的过程。
- 可以在不同的函数中使用相同的变量名,它们表示不同的数据,分配不同的内存,互不干扰,也不会发生混淆。
- 在语句块中也可定义变量,它的作用域只限于当前语句块
【示例】根据长方体的长宽高求它的体积以及三个面的面积。
#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;
}
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
2
函数调用的参数传递
函数调用原则
函数调用遵循先定义、后调用的原则,即被调函数应出现在主调函数之前。
#include <cstdio>
void _you_(int x){ //这里会出错,因为在前面看不到_my_
_my_(x);
}
void _my_(int x){
int a=10;
}
int main(){
_you_(5);
return 0;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
函数的参数传递
调用的一个函数的过程具体是怎么样的?参数又是怎么传递的呢?
#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;
}
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行三个整数的最大值
3
1 2
3 1
2 3
3
1 2 3
3 2 1
1 4 7
2
3
4
5
6
7
8
不使用函数
#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;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#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;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
发现使用了函数后,代码量变少了,可读性变高了.