Chapter 4 利用函数实现指定功能(中篇)

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 或 template ,"class"与"typename"是一样的效果,可以互换

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)="<之前,就要在定义中给出默认值

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指令,就可以把不同的文件组合在一起,形成一个文件,相当于把几百行或者几十行的代码都节约了

共同学习,欢迎指正! 

你可能感兴趣的:(开发语言,c++)