您的位置:首页 > 编程语言 > C语言/C++

C/C++函数学习总结

2018-03-22 17:03 288 查看
一,基础知识
1,函数的定义
(1)函数定义的语法形式:
数据类型    函数名(形式参数表)
{
                 函数体               //执行语句
}
函数头——函数接口,包括:
函数返回值类型       函数体中由return语句返回的值的类型。没有返回值其类型为void
函数名          用户定义标识符
形式参数表  逗号分隔的参数说明表列,缺省形式参数时不能省略圆括号。一般形式为:类型
参数1,类型 参数2,...,类型 参数n
(2)函数定义的例子
定义一个函数,返回两个数中的较大数。int max(int x,int y)
{
if(x>y) return x;
else return y;
}2 函数的声明和调用
(1)函数的声明
调用函数之前先要声明函数原型,按如下形式:
类型说明符   被调函数名(形式参数表);
例如int js(int n);也可以int js(int);(2)函数的调用
调用形式:
函数名(实际参数表)
3 函数调用方式
(1)传值调用
传值调用就是指当一个函数被调用时,根据实参和形参的对应关系将实参的值一一
复制给形参,即实参的值单向传递给形参。函数本身不对实参进行任何操作,
即使形参的值在函数中改变,实参的值也不会受到影响。

(2)传引用
引用的概念:
类型名 & 引用名 = 某变量名; 
某个变量的引用,和这个变量是一回事,相当于该变量的一个别名

int n = 4;
int & r = n;
r = 4;
cout << r; //输出 4;
cout << n; //输出 4;
n = 5;
cout << r; //输出5 (注:定义引用时一定要将其初始化成引用某个变量,不初始化编译不过。
       引用只能引用变量,不能引用常量和表达式)

引用的作用:void swap( int & a, int & b)
{
int tmp;
tmp = a; a = b; b = tmp;
}
int n1, n2;
swap(n1,n2) ; // n1,n2的值被交换(3)传地址
      如果在函数定义时将形参说明成指针,调用函数时就需要指定地址值形式的实参。这时的参数传递方式就是按地址传递方式。 按地址传递与按值传递的不同在于:形参指针和实参指针指向同一个地址。因此,被调用函数中对形参指针所指向的地址中内容的任何改变都会影响到实参。
例:#include <iostream>
using namespace std;
void swap(int*,int*);
int main()
{
int a = 3, b = 4;
cout << "a = " << a << ", b = "
<< b << endl;
swap(&a,&b);
cout << "a = " << a << ", b = "
<< b << endl;
system("pause");
return 0;
}
void swap(int *x,int *y)
{
int t = *x;
*x = *y;
*y = t;
}
4 递归函数
直接或间接调用自身的函数称为递归函数
它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。
(1)递归的基本思想
   问题分解:
   把一个不能或不好解决的大问题转化为一个或几个小问题,再把这些小问题进一步分解成更小的小问题,

   最小问题可以直接解决。   
(2)递归的关键在于找出递归定义和递归终止条件。
递归定义:使问题向边界条件转化的规则。递归定义必须能使问题越来越简单。

递归终止条件:也就是所描述问题的最简单情况,它本身不再使用递归的定义。

(3)递归算法解题通常有三个步骤:

<1>分析问题、寻找递归:找出大规模问题与小规模问题的关系,这样通过递归使问题的规模逐渐变小。
<2>设置边界、控制递归:找出停止条件,即算法可解的最小规模问题。
<3>设计函数、确定参数:设计函数体中的操作及相关参数。 

二,题型总结
1,  函数直接定义使用解决问题(非递归)
例,输入两个正整数,输出两个数的最小公倍数#include<bits/stdc++.h>
using namespace std;
int x,y;
int gcd(int,int);
int bei();
int main()
{
cin>>x>>y;
if(x<y) swap(x,y);
cout<<bei();
return 0;
}
int gcd(int x,int y) //求最大公约数
{
int r;
r=x%y;
while(r!=0)
{
x=y;
y=r;
r=x%y;
}
return y;
}
int bei() //求最小公倍数
{
return x*y/gcd(x,y); //这里x,y为全局变量
}2,函数定义中,直接或间接地出现对自身的调用(递归)
(一般用来解决大型复杂的问题)
例 :
把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。输入第一行是测试数据的数目t(0 <= t <= 20)。以下每行均包含二个整数M和N,以空格分开。1<=M,N<=10。输出
4000
对输入的每组数据M和N,用一行输出相应的K。样例输入
1
7 3
样例输出
8
代码:#include<iostream>
using namespace std;
int t,m,n;
int up(int ,int);
int main()
{
cin>>t;
while(t--)
{
cin>>m>>n;
cout<<up(m,n)<<endl;
}
return 0;
}
int up(int m,int n)
{
if(m==0||n==1)
return 1;
else if(m<n)
return up(m,m);
else return up(m-n,n)+up(m,n-1);
}
三,本章学习心得
  通过 本章的学习,我学会了构建一个具备某功能的函数来实现自己想达到的目的。通过把大量的操作过程写到构建的函数中去,从而使主函数变得简洁,增强了整个程序的可阅读性。关于构建新函数的步骤,自已一般是先考虑函数的功能,然后选择合适的参数传递方式(这个很关键,比如将两变量交换,即swap这个函数就不能使用传数值这种方式),最后就是去构思写函数体了。在函数部分最难的应该就是递归函数了,通过这段时间做oj的题目来看,递归这部分的题目都很繁杂,需要把各种情况都考虑清楚,对算法思维要求很高(自己经常两节课也写不出一道题,唉)。


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  总结