目录
一、函数相关的知识点
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,则为水仙花数,输出。题目总体难度不大,但是需要细心规划,把大问题分解为小函数去解决。
②验证歌德巴赫猜想
描述
验证“歌德巴赫猜想”,即:任意一个大于2的偶数均可表示成两个素数之和。
输入
输入只有一个正整数x。(x是偶数,x <= 2000 且 x > 2)
输出
输出这个数的所有分解形式,形式为:
x = y + z
其中x为待验证的数,y和z满足y + z = x,而且 y <= z,y和z均是素数。
如果存在多组分解形式,则按照y的升序输出所有的分解,每行一个分解表达式。
(注意数和符号之间隔一个空格)
样例输入
输入样例1: 10 输入样例2: 100
样例输出
输出样例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
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代码把题目细分为三个函数,让解题思路清晰,其中主函数结构简单,直接调用其余两个函数,在“分解”函数中,则是调用了“判断素数”函数,边分解边判断是否是素数。
三、学习函数个人心得
学习函数部分,特别重要的是细心,比如函数的声明最后是有分号的,函数的定义则没有,还有就是要讲究方法,把大问题细分,分成若干个部分,分别求解每个小部分,这样就能做到不漏细节,把握全题。
还有就是在设计某个函数时,要提前想好,设计的函数要达到什么目的,需要什么功能,在脑子中现有一个大体的设计方案,不要像无头苍蝇一样,边写边设计,这样就不能顾全大局,把握整体。
全部评论
(1) 回帖