分类
C++

C++_函数的认识与定义

一、什么是封装?​

在我们的生活中,有很多事情要去处理,但并不是每件事情都需要我们去亲力亲为。
比如,在我们想要吃饭时,爸爸妈妈会帮忙准备好热腾腾的饭菜,而每道菜肴具体是怎样制作的我们本身并不关心;在我们想要冷藏一瓶饮料的时候,只需要将饮料放入冰箱即可,至于冰箱是怎样冷藏饮料的我们并不关心;在我们想要使用计算器的时候,只需要将需要运算的数字输入进去,计算器就会自动计算出对应的结果,至于计算器是怎样运作的我们并不关心……

我们可以将常用的功能(如爸爸妈妈是怎样制作饭菜的,冰箱是如何运作的,计算器是怎么样预算的)进行封装,这样后续使用的时候,就可以直接进行调用。在计算机中,有很多函数已经封装好了,可以直接调用,我们不需要去了解这些函数具体是怎样实现的,只需要知道如何调用它们即可,然后按需设计自己的程序。

二、常见的函数

c++程序都由一个或多个函数组成,必有一个主函数main()。​在主函数中可以调用其他函数,函数之间也可以相互调用。在我们之前编程的学习过程中其实已经接触过很多常用的函数,看看你认识几个,是否能熟练使用。

  • 1.主函数 main()​
    程序执行的入口,出口。
    注意:一个程序只能有一个主函数
  • 2.最值函数​
    max(a,b) 求a和b两个数中的最大值
    min(a,b) 求a和b两个数中的最小值
    注意:参数固定为两个,a和b的数据类型应该相同
    如求三个数a,b,c的最大值可以写max(max(a,b),c)或max(a,max(b,c));
  • 3.取整函数​
    向上取整函数:ceil(a) 如ceil(1.1) 即2 ,ceil(1.0)即1
    向下取整函数: floor(a) 如floor(1.7)即1,floor(1.0)即1
    四舍五入取整函数:round(a) 如round(1.45)即1,round(1.501)即2
    注意:四舍五入取整和四舍五入保留小数位切勿弄混
  • 4.交换函数​
    swap(a,b) 交换a和b两个变量的值
  • 5.幂函数​
    pow(a,b) 求a的b次方,即a^b=a×a×a×…×a。(b个a连乘) 例pow(2,3)=2×2×2=8。
  • 6.排序函数​
    sort(数组名+开始位置,数组名+结束位置+1,cmp)
    对数组进行排序,具体讲解详见数组排序和结构体章节
  • 7.绝对值函数​
    abs(a) 求整数a的绝对值
    fabs(a) 求实数a的绝对值
  • 8.开平方函数​
    sqrt(a) 求a的开平方结果

三、函数编写格式

函数function是一段能实现一个具体、独立、完整的功能的代码。
****直接调用函数,同学们在前期的学习中已经掌握了。如果我们想自己来编写一个函数,该怎么写呢?下面就介绍一下函数编写的格式:
我们一般将被调用的函数写在当前函数的上方,具体格式如下所示

#include<bits/stdc++.h>
using namespace std;

//以下为自编函数格式:

返回值类型①  函数名②(形式参数列表③)
{

    若干行用于实现该函数功能的具体代码④;

}

int main()
{

    ......

    ...函数名(实际参数列表⑤)...;//此处调用函数\

    ......
}

注:

①返回值类型​

即自编函数运行后返回给主函数的值,分为有返回值类型(可以是int,float,double,char等等),和无返回值类型(void)。如果有返回值,则调用函数的地方应该进行接收处理,如果无返回值(类型为void)则调用函数的地方不应该进行接收处理。

②函数名​

由字母,数字,下划线组成,其中不能以数字开头。主函数的函数名必须是main,不得更改,其他的可以任意取名,最好能表示函数实现的功能。

③形式参数列表​

定义多个变量,表示该函数参数的类型即个数,当函数有多个参数时,用逗号隔开。参数个数可以有0个,1个或多个。

④具体代码​

实现该函数具体功能的代码

⑤实际参数列表​

实际传递的参数值,实际参数个数应该与被调用函数的形式参数个数相同。

四、函数编写实例参考​

1.绝对值函数:​

#include<bits/stdc++.h>
using namespace std;

int abs(int n)//函数名:abs 形式参数:n(用于接收实参)返回值类型:整型
{
    if(n<0)
    {
        return -n;
    }//利用return 语句返回需要返回的数值,如果是负数,修改为正数再返回
    else
    {
        return n;
    }//如果是正数,则返回原数字
} 

int  main()
{   
    int a;
    cin>>a;
    cout<<abs(a);//此处调用abs函数,传递实际参数为a,将返回值输出
    return 0;
}

注:

  • 语句执行过程:​ 1.主函数部分 ①int a;cin>>a; ​//程序从主函数开始执行 ②abs(a)​//调用abs函数,传递实参a给abs函数对应的形参n。 2.abs函数部分 ①n=a;​ //abs函数的形式参数n接收传递过来的实参a,即n=a; ②if(n<0) return -n; else return n; ​//将n的值取绝对值返回到调用abs函数的位置。 3.主函数部分 ①cout<<返回值;​//abs函数将算好的绝对值返回到主函数这里,利用cout语句将返回值输出。 ​(abs函数是自带函数,可以直接调用,无需自编函数,本题仅做自编函数参考)
  • 关于主调函数与被调函数间参数传递的说明:​ 1.该实例中 主调函数即为 main(),被调函数为abs()。 2.参数传递只能是单向传递,即由实际参数传给形式参数,本题当中通过cout<<abs(a),将实参a的值传递给了形式参数n只是让n来借用a的值进行相关运算,abs函数里的return n或return -n,只是函数的处理结果,并不会改变主函数main里的a值,即n值不能传递给a。 例如输入5给a
int  main()
{
  int a;
  cin>>a;//输入 -5
  cout<<abs(a)<<endl;//输出 5
  cout<<a<<endl;//输出 -5
}

a的值不会受abs()函数的影响,该是多少还是多少。

  • 关于函数的返回值应用的说明:​ 1.函数的返回值用return去定义,格式为:
    return (表达式) 表达式可以是变量,例如上例代码的return n或者return -n。
    表达式也可以是常量,比如主函数里最后的 return 0,主函数里的 return 0表示程序的正常退出。
    表达式还可以是由运算符+操作数组成的式子。 2.return是一个函数结束的标志 函数内可以有多个return,每次调用只能有一个return语句被执行。只能返回一个函数值.
    return只要执行一次,整个函数就会结束运行。 return 的返回值无类型限制,即可以是任意数据类型. 例如abs()函数
int abs(int n)//函数名:abs 形式参数:n(用于接收实参)返回值类型:整型
{
    if(n<0)
    {
       return -n;
    }//利用return 语句返回需要返回的数值,如果是负数,修改为正数再返回
    else
    {
       return n;
    }//如果是正数,则返回原数字
} 
int  main()
{
    int a;
    cin>>a;//输入 -5
    cout<<abs(a)<<endl;//输出 5
}

上述代码abs()函数里有两个返回值语句,程序只能执行其中的一个后,abs()函数就会结束。

return 可以放在函数的任何一个位置,有时候我们为了解题方便,可以在主函数里添加若干个return 0语句,让程序提前结束。例如下面代码,程序执行不到cout<<s,就已经结束了。

例如提前让主函数结束

int  main()
{
    int i,s=0;
    for(i=1;i<=10;i++)
    {
    s+=i;
    }
    return 0;//程序执行到这就正常退出了,后边的代码不再执行
    cout<<s<<endl;
    return 0;
}

函数返回值的类型和函数定义中函数的类型标识符应保持一致,如果不一致,则以函数类型为准,自动进行类型转换。

例如返回类型为char,定义的函数类型为int

int cf(int k)//函数名:cf 形式参数:k(用于接收实参)返回值类型:整型
{
    if(k<0)
    {
        return 'a';
    }//如果是负数,返回字符a
    else
    {
        return 'b';
    }//如果是正数,则返回字符b
} 
int  main()
{
    int a;
    cin>>a;
    cout<<cf(a)<<endl;
    return 0;
}
image.png

输入5,虽然cf()函数返回了字符b,但是输出的结果却为字符b的ASCII码值98,char类型转化为int类型了。

image.png

五、练一练​

1.求和
模仿上述例子,请你尝试着设计一个程序,通过调用函数的方式实现求两个整数数字的和,函数模块负责实现求两个数字的和。

代码如下:

#include<iostream>
using namespace std;

int sum(int x,int y)
{
    int s=x+y;//s保存传进来的两个数的和
    return s;//返回和 也可以直接写成return x+y
}

int main()
{
    int a,b;
    cin>>a>>b;
    cout<<sum(a,b);//调用求和函数
    return 0;
}

2.曼哈顿距离
已知A点坐标(x1,y1),B点坐标(x2,y2),分别输入x1,y1,x2,y2,求A、B两点之间的曼哈顿距离,要求将“求解曼哈顿距离的部分”封装成一个函数。
提示:平面上A点(x1,y1),B点(x2,y2)的曼哈顿距离为:|x1-x2|+|y1-y2|。
例如A(-2,1),B(1,5)
曼哈顿距离为:|-2-1|+|1-5|=3+4=5。

image.png

代码如下:

#include<iostream>
#include<cmath>
using namespace std;

double dis(double a1,double b1,double a2,double b2)
{
double a,b,c;//a,b分别表示两个点的横纵坐标之间的差值
a=abs(a1-a2);//记录横坐标的差值
b=abs(b1-b2);//记录纵坐标的差值
c=a+b;//求曼哈顿距离
return c;//返回c  也可以直接写成return a+b
}

int main()
{
double x1,x2,y1,y2,
cin>>x1>>y1>>x2>>y2;
cout<<dis(x1,y1,x2,y2);//调用dis函数
return 0;
}

3.判断素数
输入一个整数n,判断这个数是否是质数,是输出“yes”,不是输出”no“。
代码如下:

#include<iostream>
using namespace std;

bool isprime(int x)
{
    int i;
    for(i=2;i*i<=x;i++)
    {
        if(x%i==0)//找到x多余的因数
            return 0;//返回0
    }
    return 1;//循环结束没有找到x多余的因数,返回1
}

int main()
{
    int n;
    if(isprime(n)==1)
        cout<<"yes";
    else
        cout<<"no";
}

4.判断回文数,输入一个数n,判断n是否为回文数,是的话,输出“yes”,否则输出“no”。
当n位数较少时,可以用整型来声明,代码如下:

#include<iostream>
using namespace std;

int huiwen(long long x)
{
    int b=0,c;
    while(x!=0)//短除法,对x的每一位进行判断 
    {
        c=x%10;//取x的最后一位 
        b=b*10+c;//更新b 
        x=x/10;//去除x的末位 
    }
    return b;//返回倒序后的数 
}

int main()
{
    int n;cin>>n;
    if(n==huiwen(n))//是回文数 
        cout<<"yes";
    else
        cout<<"no";
    return 0; 
 } 
#include<iostream>
using namespace std;

int huiwen(long long x)
{
    int b=0,c;
    while(x!=0)//短除法,对x的每一位进行判断 
    {
        c=x%10;//取x的最后一位 
        b=b*10+c;//更新b 
        x=x/10;//去除x的末位 
    }
    return b;//返回倒序后的数 
}

int main()
{
    int n;cin>>n;
    if(n==huiwen(n))//是回文数 
        cout<<"yes";
    else
        cout<<"no";
    return 0; 
 } 
#include<iostream>
using namespace std;

int huiwen(long long x)
{
    int b=0,c;
    while(x!=0)//短除法,对x的每一位进行判断 
    {
        c=x%10;//取x的最后一位 
        b=b*10+c;//更新b 
        x=x/10;//去除x的末位 
    }
    return b;//返回倒序后的数 
}

int main()
{
    int n;cin>>n;
    if(n==huiwen(n))//是回文数 
        cout<<"yes";
    else
        cout<<"no";
    return 0; 
 } 

当n位数较多时,可以考虑使用字符串实现,代码如下:

#include<iostream>
using namespace std;

string huiwen(string s)
{
    string ss="";
    int l=s.size();
    for(int i=l-1;i>=0;i--)//倒序将字符存放到字串ss中 
    {
        ss+=s[i];
    }
    return ss;//返回倒序后字串 
}

int main()
{
    string s;
    cin>>s;
    if(s==huiwen(s))//是回文数 
        cout<<"yes";
    else
        cout<<"no";
    return 0; 
} 

六、拓展——函数的声明

能不能把被调用函数放在调用函数的后面呢?是可以的,只是要提前进行函数的声明

在调用函数之前,要先声明函数的原型,即先声明函数的返回值类型和参数类型,在所有主调函数中或所有函数定义之前,函数的声明形式如下:

返回值类型  函数名(形式参数列表);
比如练一练中求两个数字和的题目,如果提前声明max函数,具体函数的实现如下:

1.求和
模仿上述例子,请你尝试着设计一个程序,通过调用函数的方式实现求两个整数数字的和,函数模块负责实现求两个数字的和。

代码如下:

#include<iostream>
using namespace std;

int sum(int x,int y)
{
    int s=x+y;//s保存传进来的两个数的和
    return s;//返回和 也可以直接写成return x+y
}

int main()
{
    int a,b;
    cin>>a>>b;
    cout<<sum(a,b);//调用求和函数
    return 0;
}

发表回复