4.6 函数的递归调用
1.定义:在调用一个函数的过程出现直接或者间接调用函数本身,这就称为函数的递归调用
且包含递归调用的函数称为递归函数
例如:int f( int x)
{
int x,y;
z=f(y)
}
2.条件:
a:存在限制条件,当满足这个限制条件时,程序就不能在次进行了
b:每次完成递归时,递归函数应离这个条件越来越近。
若果不这样,就会发生栈溢出(stack over flow)的问题
4.7 内置函数(内嵌函数、内联函数)
1.定义:C++提供了一种高效的方法,即在编译时所调用函数的代码直接嵌入到主调函数中,而不是将流程转出去,这种嵌入到主调函数中的函数称为内置函数
2.用法:只需在函数首行的左端加一个关键词inline即可
#include
using namespace std;
inline int max(int,int,int);
int main()
{
int i=0,j=20,k=30,m;
m=max(i,j,k);
cout<<"max="<a)a=b;
if(c>a)a=c;
return a;
}
补充—内嵌函数
a:当然如果把inline去掉,也是可以的,那就是全局声明
b:声明函数和定义函数时可以同时写inline,也可以只在函数声明时加inline
c:内置函数不能包括复杂的控制语句,如循环语句和switch语句等
d:只有那些规模较小而又被频繁调用的简单函数,才适用inline
4.8 函数重载“一物多用”
1.在一般过程中,一般是一个函数对应一种函数,但有时我们要实现是同一类的功能,只是有些系统不一样,C++允许用同一函数名定义多个函数,而这些函数的参数个数和参数和参数类型可以不同,这就是函数重载,一个函数名多个用法
//函数原型
int max1 (int a,int b,int c)
double max2(double a,double b,double c)
long max3(double a,double b,double c)
例题:求三个数中的最大数
#include
using namespace std;
int main()
{
int max(int ,int ,int);//输入的值满足哪个就调用哪个
double max(double,double,double);
long max(long,long);
int i1,i2,i3,i;
cin>>i1>>i2>>i3;
i=max(i1,i2,i3);
cout<<"i_max="<>d1>>d2>>d3>>d;
d=max(d1,d2,d3);
cout<<"d_max:"<>l1>>l2;
l=max(l1,l2);
cout<<"l_max"<a) a=b;
if(c>a) a=c;
return a;
}
double max(double a,double b,double c)
{
if(b>a) a=b;
if(c>a) a=c;
return a;
}
long max (long a,long b)
{
long max=0;
if(b>a)
max=b;
if(b
注意⚠️:重载函数的参数个数,参数类型或参数顺序至少要有一个不同
4.9 函数模板
1.C++提供了函数模板 ,实际上建立了一个通用函数,其函数类型和形参类型不具体指定,用一个虚拟的类型来代表,这个通用函数就称为函数模板
2.好处:凡是函数体相同的函数都可以用这个模板来代替,不必定义多个函数,只须在模板中的定一次即可,要用的时候调用里面的就可以
3.形式:template
4.局限:函数模板只适用于函数体相同,函数参数相同,函数类型不同的情况
根据上面的例题改:
#include
using namespace std;
template //模板声明,其中的T为类型参数
T max(T a,T b,T c)
{
if(a>b) a=b;
if(c>b) a=c;
return a;
}
int main()
{
int x1=2,x2=2,x3=3,x;
double y1=2.2,y2=3.14,y3=3.3,y;
x=max(x1,x2,x3);
y=max(y1,y2,y3);
cout<<"x_max:"<
4.10 有默认参数的函数
1.这会使形参不一定从实参取值,若函数在声明时对形参进行初始化,那么形参不从实参取值时,那么他的值就是我们给的值,例如:float area (float r=6.5);//这是声明
2.可以对所有的形参给一个默认值,也可以都不给,或者只给一部分,且有默认值的参数必须放在最右端,在调用有默认参数的函数时,实参的个数可以与形参不同,实参未给定的,从形参的默认值中得到
例题:求两个或者3个正整数中的最大数
#include
using namespace std;
int main()
{
int max(int,int,int c=0);
int a,b,c;
cin>>a>>b>>c;
cout<<"max(a,b,c)="<a)a=b;
if(c>a)a=c;
return a;
}
注意⚠️:
a:如果函数的定义在函数调用之前,就要在定义中给出默认值
b:如果函数的定义在函数调用之后,就在要在声明中给出默认值
c:如果在声明中已经给出了默认值,而在定义函数时也给出了默认值,有些编译器会出现“重读定义默认值的错误”,但是有一些编译系统不会报错,那么这个时候就会以先遇到的为准
d:一个函数不能即作为重载函数,又作为有默认参数的函数,因为如果他即使重载函数,又是有默认参数的函数话,当调用时少写一个参数的话,就不知道调用的是重载函数,还是有默认参数的函数
4.11 局部变量和全部变量
1.局部变量:在一个函数内部定义的变量,他只在本函数范围内有效
a:主函数main中定义的变量(m,n)也只在主函数中有效,不会在主函数中定义而在整个文件或程序有效,在主函数也不能使用其他函数定义的变量
b:不同的函数可以使用同名的变量,不会混淆,因为不同的时间段内存单元中占不同的单元
c:在复合语句中定义变量,也只在复合语句(称为分程序或程序块)中有效
d:形式参数也是局部变量,只在自己的函数部分有效
e:在函数声明中出现的参数名并不是实际存在的变量,不能被引用,可以理解为形参是一个有名无实上的家伙
2.全局变量:在函数外定义的变量,在从定义的那一行开始到本程序结束都是有效的
注意⚠️:若局部变量与全局变量重名,则在局部变量作用的部分全局变量都会被屏蔽
3.作用域(scope):变量的有效范围
a:分类:文件作用域(file scope)、函数作用域(function scope)、块作用域(block scope)、函数原型作用域(function prototype)只有文件作用域是全局的,其他都是局部的
4.12 关于变量的声明和定义
1.函数一般有两个部分:声明部分+执行语句
2.两者的关系:函数的声明是函数的原型,而函数的定义是函数功能的确定
3.对于函数:它的声明就是函数的原型,而函数的定义不在函数声明部分范围内,它是一个文件中的独立模块
4.对于变量:
a:一种是需要建立存储空间的(定义性声明或者称为定义)
b:一种是不需要建立存储空间的(引用性声明)
最关键的:就记住建立了存储空间的声明称为定义,没有存储空间的声明称为声明
4.13 内部函数和外部函数
1.内部函数:是一个只能被本文件中其他函数调用的函数
a:形式:static 类型标识符 函数名(形参表)
b:别名:静态函数
d:作用:次函数只局限于所在文件,static是文件局部化,不能被其他文件引用
2.外部函数:若在最左端加一个extern,表示此函数为外部函数,可以被其他文件引用
a:若省略extern,都是默认为外部函数,在需要调用此函数的文件中,用extern对此函数声明
4.14 头文件
1.内容:对类型的声明+函数的声明+内置(inline)函数的定义+宏定义+全局变量定义+外部变量声明+还可以包含其他头文件
好处:由于有了#include指令,就可以把不同的文件组合在一起,形成一个文件,相当于把几百行或者几十行的代码都节约了
共同学习,欢迎指正!