第六章 函数
☆知识点
1. 函数定义:函数需要先定义然后才能使用.
函数定义的一般形式为:
类型标识符 函数名(形参表)(☜形参表外面的括号内部可以为空,但是括号不能省略)
{
语句;
}(注: 花括号后面没有分号,注意与类的区分)
在函数的定义中,形参只是一个占位符,标志着在形参出现的位置应该有一个什么类型的数据.
★ C/C++用函数写程序的典型结构如下:
第一部分: 预处理指令
符号常量定义
函数声明
第二部分: 主函数
第三部分: 函数定义
2. 函数的调用:
函数名(实参表);(注:该条语句是写在主函数内部的,实参表与定义函数中的形参表对应,实参可以是常量、变量,还可以是表达式,如果实参中存在变量,则在函数调用时,变量应该是"有确定值的")
【语义】为函数分配存储空间,执行函数.被其他函数调用的函数成为被调用函数,调用其他函数的函数,称为调用函数.
3. 引用的概念
引用的概念很简单 表达方式是: 类型名&引用名=某一变量名(注:引用名与某一变量名虽名字不同,但是这两个是同一个变量,而且引用只能引用变量,不能引用常量和表达式)
学完函数,我们知道C++中函数调用时有三种参数传递方式,分别是: 按值传递、地址传递、引用传递.下面是我对这三种传递方式的总结.
a) 按值传递:
过程:首先计算出实参表达式的值,接着给对应的形参变量分配一个存储空间,然后把已求出的实参表达式的值一一存入到形参变量分配的存储空间中,成为形参变量的初值,供被调用函数执行时使用.
特点:被调用函数本身不对实参进行操作,即使形参的值在函数中发生了变化,实参的值也完全不会受到影响,仍为调用前的值,故两数交换的函数不能采用按值传递这种方式
b)地址传递:
如果在函数定义时将形参说明成指针,调用函数时就需要指定地址值形式的实参,这时的参数传递方式就是按地址传递方式.
按地址传递与按值传递的不同在于:形参指针和实参指针指向同一个地址.因此,被调用函数中对形参指针所指向的地址中内容的任何改变都会影响到实参.
c)引用传递:
如果以引用为参数,则既可以使得对形参的任何操作都能改变相应的数据,又使得函数调用显得方便、自然. 引用传递方式是在函数定义时在形参前面加上引用运算符"&".
递归函数是函数中的其中一种
递归函数:直接或间接调用自身的函数称为递归函数.它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解.
递归的基本思想
递归的基本思想可以用四个字概括,即"问题分解".也就是说把一个不能或不好解决的大问题转化为一个或几个小问题,当然最小的问题可以直接解决.
递归的关键在于找出递归定义和递归终止条件.
递归定义:使问题向边界条件转化的规则,递归定义必须使问题越来越简单.
递归终止条件:也就是所描述的问题的最简单情况,它本身不再使用递归的定义.
递归算法解题通常有三个步骤
1) 分析问题,寻找递归: 找出大规模问题与小规模问题的关系,这样通过递归使问题的规模逐渐变小.
2) 设置边界,控制递归: 找出停止条件例如:求n的阶乘,使问题逐渐分解,最后分解为求1的阶乘,求1的阶乘也即是最小的问题,可以直接解决的问题,也是递归的终止条件.
3) 设计函数,确定参数: 设计函数体中的操作及相关参数.
☆题型总结
用函数写程序其实题型大多都一样,只是调用的函数不同. 以哥德巴赫猜想这一道题来总结一下题型.
描述
验证“歌德巴赫猜想”,即:任意一个大于2的偶数均可表示成两个素数之和。
输入
输入只有一个正整数x。(x是偶数,x <= 2000 且 x > 2)
输出
输出这个数的所有分解形式,形式为:
x= y + z
其中x为待验证的数,y和z满足y + z = x,而且 y <= z,y和z均是素数。
如果存在多组分解形式,则按照y的升序输出所有的分解,每行一个分解表达式。
注意数和符号之间隔一个空格。
样例输入:
输入样例1:
10
输入样例2:
100
样例输出
输出样例1:
10= 3 + 7
10= 5 + 5
输出样例2:
100= 3 + 97
100= 11 + 89
100= 17 + 83
100= 29 + 71
100= 41 + 59
100= 47 + 53
#include<iostream>
#include<cmath>
usingnamespace std;
intprime(int x);//函数声明,简单点说 也就是占个位置. 因为要想调用函数,必须先定义才能调用,这条语句就是起一个'占位'的作用.
intmain()//下面为主函数,主函数内会调用我们前面声明的函数
{
int m,n1,n2;
cin>>m;
for(int n1=2;n1<=m/2;n1++)
{
n2=m-n1;
if(prime(n1))//调用函数,n1为实参.
if(prime(n2))//也是调用函数,n2为实参.
cout<<m<<" "<<"="<<""<<n1<<" "<<"+"<<""<<n2<<endl;
}
return 0;
}
intprime(int x)//(函数定义,x为形参)
{
int j=2;
while(j<=sqrt(x)&&x%j!=0)
j++;
if(x%j==0)
return 0;
else
return 1;
}
函数的题型基本就是三个步骤
①预处理指令
符号常量定义
函数声明
② 主函数
③函数定义
☆个人心得
我个人觉得函数这部分其实挺简单的,就是函数中的递归函数有点难,理解起来简单,但写起代码来,不太容易想,毕竟是新知识,可能以后做的题多了,慢慢地也就好了.而且函数也挺有用的,比如以前写的那个判断区间素数的题,如果用以前的方法写,可能需要写很长很长的一串代码,但是用最近学的函数来写,效果就不一样了,我们只需要将调用的函数写成判断素数的形式,然后在主函数中,运用一维数组判断区间内的每一个数是否为素数,判断一个数是否为素数时直接调用定义的函数即可. 函数可以使复杂问题简单化,比如,一些难度较大的问题,用函数写就会相对简单. 刚学函数时,感觉用函数写代码挺难的,但是通过做题,就感觉用函数写代码越来越简单,当然学其他知识也一样,刚开始都会感觉难,但是当你逐渐运用所学知识时,就会有不同的感觉,而且运用新知识,还可以加强对新知识的记忆.