C++函数总结

目录

一、函数相关的知识点

二、函数题型题目总结

三、学习函数个人心得

一、函数相关的知识点

1.   标准库中的函数  在C++的标准库中,有很多已经“造好的”函数,我们只要#include相应的头文件,就可以在主函数中调用头文件中包含的函数,比如cmath头文件,就包含了:

1、 三角函数
  double sin(double);正弦
  double cos(double);余弦
  double tan(double);正切
2 、反三角函数
  double asin (double); 结果介于[-PI/2,PI/2]
  double acos (double); 结果介于[0,PI]
  double atan (double); 反正切(主值),结果介于[-PI/2,PI/2]
  double atan2 (double,double); 反正切(整圆值),结果介于[-PI,PI]
3 、双曲三角函数
  double sinh (double);
  double cosh (double);
  double tanh (double);
4 、指数与对数
  double frexp(double value,int *exp);这是一个将value值拆分成小数部分f和(以2为底的)指数部分exp,并返回小数部分f,即f*2^exp。其中f取值在0.5~1.0范围或者0。
  double ldexp(double x,int exp);这个函数刚好跟上面那个frexp函数功能相反,它的返回值是x*2^exp
  double modf(double value,double *iptr);拆分value值,返回它的小数部分,iptr指向整数部分。
  double log (double); 以e为底的对数
  double log10 (double);以10为底的对数
  double pow(double x,double y);计算x的y次幂
  float powf(float x,float y); 功能与pow一致,只是输入与输出皆为单精度浮点数
  double exp (double);求取自然数e的幂
  double sqrt (double);开平方
5 、取整
  double ceil (double); 取上整,返回不比x小的最小整数
  double floor (double); 取下整,返回不比x大的最大整数,即高斯函数[x]
6 、绝对值
  int abs(int i); 求整型的绝对值
  double fabs (double);求实型的绝对值
  double cabs(struct complex znum);求复数的绝对值
7 、标准化浮点数
  double frexp (double f,int p); 标准化浮点数,f = x 2^p,已知f求x,p (x介于[0.5,1])
  double ldexp (double x,int p); 与frexp相反,已知x,p求f
8 、取整与取余
  double modf (double,double*); 将参数的整数部分通过指针回传,返回小数部分
  double fmod (double,double); 返回两参数相除的余数
9 、其他
  double hypot(double x,double y);已知直角三角形两个直角边长度,求斜边长度
  double ldexp(double x,int exponent);计算x*(2的exponent次幂)
  double poly(double x,int degree,double coeffs []);计算多项式
  int matherr(struct exception *e);数学错误计算处理程序 

包含了头文件<cmath>后,就可以直接使用这些函数了。

2.    打造自己的工具—“自定义函数

如果C++标准库中没有自己需要的函数,我们就可以“自定义函数”:

函数的声明:让计算机知道,我们自定义了一个函数,这就是函数的声明(Declare)。

返回值类型 函数名 (参数表);

例如:判断素数的函数

Bool Prime(int x);

注意:在函数的声明最后是有分号的,而函数的定义没有。

函数的定义 : 自定义的函数是怎运作的,内部结构是什么,这就是函数的定义(Define)。

返回值类型 函数名 (参数表)
{
        语句1;
        ……
        语句n;
}

例如:判断素数的函数

Bool Prime(int x)
{
    For(int i=2;i<=x/2;i++){
               If(x/i==0)
               Return false;//被整除,不是素数,返回false
    }
    Return true;//是素数,返回true
}

(声明表示该函数存在,而定义表示该函数怎么去运行,在调用函数之前,必须先声明函数)

3.    三种调用方式

调用类型 描述
传值调用 该方法把参数的实际值复制给函数的形式参数。在这种情况下,修改函数内的形式参数对实际参数没有影响。
指针调用 该方法把参数的地址复制给形式参数。在函数内,该地址用于访问调用中要用到的实际参数。这意味着,修改形式参数会影响实际参数。
引用调用 该方法把参数的引用复制给形式参数。在函数内,该引用用于访问调用中要用到的实际参数。这意味着,修改形式参数会影响实际参数。

①  传值调用

#include<iostream>
using namespace std;
int Leo(int x,int y);//自定义函数求x,y乘积
int main()
{
    int a,b;
    cin>>a>>b;
    cout<<Leo(a,b);//输出a*b
    return 0;
}
int Leo(int x,int y)
{
return x*y;
}

②  指针调用

#include<iostream>
using namespace std;
void Leo(int *x,int *y);//自定义函数交换x,y
int main()
{
    int a,b;
    cin>>a>>b;
    Leo(&a,&b);//交换a,b
    cout<<a<<endl<<b;//输出交换后的a,b
    return 0;
}
void Leo(int *x,int *y)
{
    int temp=*x;
    *x=*y;
    *y=temp;
}

③  引用调用

引用调用就像是给已声明的变量起一个“绰号”—引用名

变量数据类型 &引用名=已声明的变量名;

Example ①

#include<iostream>
Using namespace std;
Int main()
{
    Int a=2;
    Int &b=a;//给变量a起了个绰号叫b
    cout<<a;//输出2
    cout<<b;//输出2
    a++;
    cout<<a;//输出3
    cout<<b;//输出3
    b++;    //对b操作就相当于对a操作,所以b++相当于a++
    cout<<a;//输出4
    cout<<b;//输出4    
    return 0
 }

Example ②

#include<iostream>
Using namespace std;
void swap(int &x,int &y);//自定义交换函数
Int main()
{
  int a=2,b=3;
  swap(a,b);
  cout<<a<<endl;//交换后 输出3
  cout<<b<<endl;//交换后 输出2
  return 0;
}
void swap(int &x,int &y)//对x,y操作,就是对 a,b 操作 x,y是 a,b 的 “绰号”
{
    int temp;
    temp=x;
    x=y;
    y=temp;
}

4.函数重载(函数重载的本质就是多个函数共用同一个函数名)

#include<iostream>
using namespace std;
int myabs(int a);//自定义求绝对值函数
float myabs(float a);
double myabs(double a);
int main()
{
    int a=-1,b=2;
    float c=-2.2f,d=3.9f;
    double e=-3e-9,f=3e6;
    cout<<"a="<<myabs(a)<<endl;
    cout<<"b="<<myabs(b)<<endl;
    cout<<"c="<<myabs(c)<<endl;
    cout<<"d="<<myabs(d)<<endl;
    cout<<"e="<<myabs(e)<<endl;
    cout<<"f="<<myabs(f)<<endl;
    return 0;
}
int myabs(int a){
    cout<<"int abs"<<endl;
    return (a>=0?a:-a);//如果a>=0 则返回a 否则返回-a
}
float myabs(float a){
    cout<<"float abs"<<endl;
    return (a>=0?a:-a);//如果a>=0 则返回a 否则返回-a
}
double myabs(double a){
    cout<<"double abs"<<endl;
    return (a>=0?a:-a);//如果a>=0 则返回a 否则返回-a
}
//运行结果
int abs
a=1
int abs
b=2
float abs
c=2.2
float abs
d=3.9
double abs
e=3e-009
double abs
f=3e+006




二、函数题型题目总结

①水仙花数

描述

所谓水仙花数指一个三位数,其各位数字立方和等于该数本身。

输入无输出100(包括100)到1000之内的水仙花数(不包括1000)样例输入
样例输出
153 370 371 407


AC代码:


#include<iostream>
using namespace std;
int n;
int sx(int i);//自定义求 i 各位立方和函数
int main()
{
  for(int i=100;i<=999;i++)
    {
        if(sx(i)==i)//如果立方和等于该数本身  则为水仙花数  输出
        cout<<i<<" ";
    }
  return 0;
}
int sx(int i)//自定义求 i 各位立方和函数
{
   int sum=0,temp;
   while(i!=0)
   {
     temp=i%10;//求该数的每一位数
     sum=sum+temp*temp*temp;//累加各位的平方和
     i=i/10;
   }
   return (sum);
}

题目总结:

题目要求输出100-1000内的水仙花数,所以用一个For循环100-1000,如果是水仙花数,则输出该数。自定义函数判断是否是水仙花数——该函数先求出i的每一位数,然后求立方累加,若所得Sum==i,则为水仙花数,输出。题目总体难度不大,但是需要细心规划,把大问题分解为小函数去解决。

②验证歌德巴赫猜想

<dl class="problem&#45;content"> <dt> 描述 </dt> <dd>

验证“歌德巴赫猜想”,即:任意一个大于2的偶数均可表示成两个素数之和。

</dd> <dt> 输入 </dt> <dd> 输入只有一个正整数x。(x是偶数,x <= 2000 且 x > 2) </dd> <dt> 输出 </dt> <dd> 输出这个数的所有分解形式,形式为:
x = y + z
其中x为待验证的数,y和z满足y + z = x,而且 y <= z,y和z均是素数。
如果存在多组分解形式,则按照y的升序输出所有的分解,每行一个分解表达式。
(注意数和符号之间隔一个空格)
</dd> <dt> 样例输入 </dt> <dd>
输入样例1:
10

输入样例2:
100
</dd> </dl>
<dl class="problem&#45;content"> <dt> 样例输出 </dt> <dd>
输出样例1:
10 = 3 + 7
10 = 5 + 5

输出样例2:
100 = 3 + 97
100 = 11 + 89
100 = 17 + 83
100 = 29 + 71
100 = 41 + 59
100 = 47 + 53
</dd> </dl>

AC代码:

#include<bits/stdc++.h>
using namespace std;
int prime(int i)//自定义函数-->判断是否是素数
{
    int flag=0,j;
    for(j=2;j<=sqrt(i);j++)
    {
         if(i%j==0)
           flag=1;//不是素数返回 1
    }
return flag;//是素数返回 0
}
int Leo(int num)//自定义分解num函数
{
   int i,k,w,e;
   for(i=3;i<=num/2;i=i+2)
  {
     w=0;
     e=0;
     w=prime(i);//i是素数  w为0   否则为1
     if(w==0)//i是素数
       {
          k=num-i;
          e=prime(k);//判断 num-i 是否是素数
       }
       if(w==0 && e==0)//if i 和 num-i 都是素数   则输出 num = i + k
       cout<<num<<" = "<<i<<" + "<<k<<endl;
  }
}
int main()
{
   int num;
   cin>>num;//输入一个数
   Leo(num);//分解该数
   return 0;
}

题目总结:

题目有几个“小坑”,比如,在输出的时候,要求第一个数小于第二个数,并且符号之间有空格,仔细审题还是不会出错的。AC代码把题目细分为三个函数,让解题思路清晰,其中主函数结构简单,直接调用其余两个函数,在“分解”函数中,则是调用了“判断素数”函数,边分解边判断是否是素数。


三、学习函数个人心得

    学习函数部分,特别重要的是细心,比如函数的声明最后是有分号的,函数的定义则没有,还有就是要讲究方法,把大问题细分,分成若干个部分,分别求解每个小部分,这样就能做到不漏细节,把握全题。

    还有就是在设计某个函数时,要提前想好,设计的函数要达到什么目的,需要什么功能,在脑子中现有一个大体的设计方案,不要像无头苍蝇一样,边写边设计,这样就不能顾全大局,把握整体。