函数学习总结
一.函数
1.为什么定义函数,使用函数
在程序的设计过程中,会在许多地方出现想同的代码,为了减少代码数量,让程序变得更加美观,此时可以将这段程序单独作为一个整体,并用标识符起一个名字,当时使用时,直接调用函数名即可。这段程序叫作子程序,就是我们所说的函数。
2. 函数的定义
(1) .定义的语法形式
数据类型 函数名(形式参数表)
{
函数体; //函数的执行语句.
}
说明:
l void 表示无返回值.
l 函数名不能是main.
l 函数不允许嵌套定义,但可以嵌套调用(递归).
l 函数只有调用时才会发挥作用,否则不会运行.
(2) .样例
定义一个函数比较大小
int max (int x.int y)
{
return x>y? x:y;
}
该函数表示返回整数,返回接受的两个实参中大的那一个.
(3) .函数的形式
l 无参函数.
没有参数传递的函数(即没有形式参数表).
l 有参函数.
最为普通的函数
l 空函数
没有执行语句,只有一对花括号,多数为了以后修改bug时用的
2. 函数的声明和调用
(1).函数的声明
函数调用时必须要先声明函数原型,或者这个函数在主函数上面定义,并写出函数体.函数如下形式声明:
数据结构 被调函数名(含有类型说明的形式参数表);//;是最重要的
样例:
int max(int a,int b);
int max(int ,int );
// 两种形式都对
(2) .函数的调用
函数名(实参列表);//;不要忘了
样例:
int mian()
{
int a=4;
int b=5;
max(a,b);
}
(3) .函数的返回值
return 表达式;
return ;//表示无返回值,只是结束函数,并返回
当函数无返回值时,可以不用写return;
(4) .函数的传值调用
函数传值调用的特点是将被调函数的实参表中的实参值依次对应地传递给被调用函数的形式参表中的形参.要求形参与实参的类型相同.
这种方式是将实参赋值一个给形参,形参的计算与主函数内的实参无关,,称为单向值传递.
样例:
#include<iostream>
using namespace std;
void swap(int a,int b)
{
int temp;
temp=a;
a=b;
b=temp;
}
int main()
{
int c=1;
int d=2;
swap(c,d);
cout<<c<<" "<<d;
return 0;
}
(5) .函数的传址调用
这种方式是将实参的地址传递给形参,这是形参是指针,即让形参的指针指向实参的地址,实际上就是一个变量,两个名(表达式),这是一种可以改变实参变量的方法.
样例:
#include<iostream>
using namespace std;
void swap(int &a,int &b)
{
int temp;
temp=a;
a=b;
b=temp;
}
int main()
{
int c=1;
int d=2;
swap(c,d);
cout<<c<<" "<<d;
return 0;
}
说明:&表示取地址的标志,即取地址符
还有一种是用指针来表示
#include<iostream>
using namespace std;
void swap(int *a,int *b)
{
int temp;
temp=*a;
*a=*b;
*b=temp;
}
int main()
{
int c=1;
int d=2;
swap(&c,&d);
cout<<c<<" "<<d;
return 0;
}
说明:指针变量前面 * 表示取值
(6) .全局变量与局部变量及它们的作用域
定义在函数外部没有被花括号火起来的变量称为全局变量,作用域是从函数定义的位置开始到文件的结束.
l 可以在任何一个函数中使用
l 过多的使用全局变量会降低程序的通用性
l 过多的使用全局变量会增加程序的调试难度
l 全局变量会一直占用内存空间
l 全局变量可以定义很大的数组
l 全局变量的初始值默认为零
定义在函数内部的变量称为局部变量,(这个函数是广义上的函数,及一对花括号内部)
l 变量的内存空间只保留到这个函数结束,其中的值在下一个函数内无法使用
l 在不同函数内部可以使用相同的符号表示不同的不同的变量
l 局部变量可以与全局变量重名,但在相同的作用域内局部变量有效二全局变量无效,即局部变量能屏蔽全部变量
l 局部便能量的初始值随机,而且数组不能定义过大
二. 指针
(1) .指针变量定义的一般形式
类型说明符 *变量名;
l 类型说明符表示的指针指向的元素的类型
(2) .指针变量的初始化的方法:
int a;
int *p=&a
//或者:
int a;
int *p;
p=&a;
详细如图解释:
指针变量同普通变量一样,使用之前不仅要定义说明,而且必须被赋予具体的值,未经赋值的指针变量不能使用。
(3) .指针的引用与运算
&表示取地址
对应关系
初始化方法
l 指针的++ 与 -- 运算表示的是取当前内存位置的下一个或上一个位置
(4) .指针与数组的关系
l 指向数组的指针变量称为数组指针变量
l 指针表示的是数组的首地址
定义:
类型说明符 *指针变量名;
*指针变量名=数组名;
这时可以直接拿数组名当指针用
样例:
int a[10];
int *p;
*p=a;
l 可以用怕p[i]的形式来访问a的数组元素
l 可以用*(p+i)的形式来访问a的数组元素
l 实际上数组名就是一个指针,但是不是变量,是一个定量
l 指针同样可以看成数组名(传说中动态数组的一种)
(5) .指针与函数的关系
l 指针同样可以作为函数的形参变量(样例在传址变量那里)
l 指针变量做参数时,调用时要用&(取地址符)(同样,上面有样例)
l 指针变量改变时,主函数内的值同样发生改变
三. 递归
(1) .定义
在函数的定义中,其内部操作又直接或间接的调用自身,称这样的程序叫作嵌套定义或递归定义.
(2).递归的特点
l 将一个大型的复杂的问题层层转化为与原问题相似的规模较小的问题来计算.
l 降低了计算量
l 开始标志:使问题向边界条件转化的规则。递归定义必须能使问题越来越简单。
l 终止标志:也就是所描述问题的最简单情况,它本身不再使用递归的定义。
l 递归的次数要有限次
l 注意递归的返回值
l 必须有一个出口,即递归停止的标志
(3) 递归实现的步骤
l 分析问题、寻找递归:找出大规模问题与小规模问题的关系,这样通过递归使问题的规模逐渐变小。
l 设置边界、控制递归:找出停止条件,即算法可解的最小规模问题。
l 设计函数、确定参数:设计函数体中的操作及相关参数