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,则为水仙花数,输出。题目总体难度不大,但是需要细心规划,把大问题分解为小函数去解决。②验证歌德巴赫猜想- 描述
验证“歌德巴赫猜想”,即:任意一个大于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代码把题目细分为三个函数,让解题思路清晰,其中主函数结构简单,直接调用其余两个函数,在“分解”函数中,则是调用了“判断素数”函数,边分解边判断是否是素数。
学习函数部分,特别重要的是细心,比如函数的声明最后是有分号的,函数的定义则没有,还有就是要讲究方法,把大问题细分,分成若干个部分,分别求解每个小部分,这样就能做到不漏细节,把握全题。 还有就是在设计某个函数时,要提前想好,设计的函数要达到什么目的,需要什么功能,在脑子中现有一个大体的设计方案,不要像无头苍蝇一样,边写边设计,这样就不能顾全大局,把握整体。
|