C++ 函数讲解与一本通平台讲解
C++ 函数讲解,这次,我们迎来了较后一个基础语言的运用 —— 函数
为什么要有函数
程序语言中的函数,并不是数学中的函数,而是对一些代码的封装,从而可以被其它函数调用,例如我们打的 **in 函数,它也是一个函数,它是一个特别的函数,代码的一切,都要从这里说起,就像一篇文章的开头
#include<iostream>
using namespace std;
int **in()//**in函数
{
//代码...
}
同时,我们在没有学习函数之前,我们都在使用函数,例如
scanf("%d",&n);
//scanf()也是一个函数,这是我们在调用它
printf("%d\n",n);
//printf()同样也是一个函数
sqrt(9);
//sqrt()也是一个函数,用于求算术平方根
//还有很多函数...
函数的作用显而易见,例如有一个代码,要求求出从 n 到 m 中的所有素数,如果全部都打在 **in 函数当中,我们就会发现有着一些不方便的地方
#include<iostream>
#include<cstdio>
#include<c**th>
using namespace std;
int **in()
{
int i,j,n,m;
bool flag;
scanf("%d%d",&n,&m);
if(n<2) n=2;
for(i=n;i<=m;i++)
{
flag=true;//需要定义一个新的变量
for(j=2;j<=sqrt(i);j++)//我们需要定义一个新的变量
{
if(i%j==0)
{
flag=false;
break;
}
}
if(flag) printf("%d\n",i);//输出
}
return 0;
}
好像也不会不方便... ( 事例不够好... )
那么如果我们声明了一个函数
#include<iostream>
#include<cstdio>
#include<c**th>
using namespace std;
bool prime(int x)//定义的函数
{
for(int i=2;i<=sqrt(x);i++) if(x%i==0) return false;
return true;
}//函数的实现
int **in()
{
int i,n,m;
scanf("%d%d",&n,&m);
if(n<2) n=2;
for(i=n;i<=m;i++) if(prime(i)) printf("%d\n",i);//超级简单的代码
return 0;
}
就可以少定义两个变量......吗
函数的作用绝不止于此,有一些算法的实现是通过函数来实现的,可见函数的重要性
函数的作用以及结构
加入函数那么到底可以什么呢
首先,函数可以让我们输入一些数据,然后进行加工,较后在返回出来,就像一个工厂
函数分为几个部分
函数的类型,就如同变量一样,函数也是有类型的,这个函数的类型决定了函数的返回类型
函数的名称,这个就是函数的名字,我们要使用它时,我们就需要打出它的名字
函数的参数 ( 不一定有 ),这个就是函数的加工原材料,函数用它们作为参数来进行加工成品
函数的实现,这个就是指定函数要做什么,怎么做
函数的返回 ( 不一定有 ),这个就是函数返回成品的方式
这几个部分共同组成了函数
int MyFunction(int a,int b)
{
return a+b;
}
//其中int为类型
//MyFunction为函数名
//int a,int b为参数
//{ }花括号内为函数的实现
//return a+b为函数的返回
这样,我们就初步认识了函数
函数的类型
与变量类似,函数也有类型。函数的类型就是反映了它的返回值的类型,如
int MyFunction1();//返回int类型
bool MyFunction2();//返回bool类型
char MyFunction3();//返回char类型
long long MyFunction4();//返回long long类型
float MyFunction5();//返回float类型
double MyFunction6();//返回double类型
string MyFunction7();//返回string类型
...
这些类型都反映了它返回的值得类型
那么除了这些类型,还有什么吗,当然,如
int* MyFunction8();//指针类型
struct node
{
int a,b;
}
node MyFunction9();//甚至还可以自己使用创造的结构体
void MyFunction10();
//在特殊类型中,我们必须知道的就是这个类型
//void类型表示这个函数不会返回任何值(也不能返回任何值)
//如果想要退出就要使用return;后面不跟任何东西即可
在这里 void 类型需要我们认识,其他 ( 如指针类型,结构体等等 ) 暂时不需要了解
void 类型的函数主要是更改全局变量
函数的名称
函数的名称与变量的名称要求相同,但是不能与变量或函数重名
例如
int MyFunction(int a,int b)
{
return a+b;
}
int MyFunction;//这样是会报错的
int **in()
{
int MyFunction;//这样是允许的
}
以上就是一个重名的例子
函数的参数
函数的参数就是函数的原材料,它可以没有,函数的类型多种多样,如
int MyFunction(int a);
int MyFunction2(bool b);
值得注意的是,在函数当中定义的参数,它是隶属于该函数的,不能被其它函数使用
另外,函数的参数是可以有默认设置的,但是设置默认参数有个条件,就是必须是后面开始设置默认参数,例如
int MyFunction1(int a,int b=1);//参数b默认为1
int MyFunction2(int a=1,int b);
//这样是不允许的,可以将它改为MyFunction3的样子,而且具有同样的效果
int MyFunction3(int b,int a=1);
int MyFunction4(int a,int b=1,int c=1)//当然多个有默认值得参数也是可以的
还有一个点就是如果你先声明了一个函数,然后在别的地方写它的实现,那么在实现处就不再需要填写它的默认参数
函数的实现
函数声明过后,就需要实现了,函数的实现其实很简单,就是在函数的花括号中写一些代码,利用传输进入函数的参数或全局变量进行计算,较后返回即可
bool MyFunction(int a,int b,int c)
{
if(a+b==c) return true;
else false;
}
以上是一个例子
函数的返回
函数在计算完成之后,一般都需要返回一个值,那么这时候就需要用到返回 return 了
return a;
return b;
...
return 在我们写代码中时会用到,例如 **in 函数中较后的 return 0;
在函数中,return 返回的变量必须与函数的类型相符,如果不相符的话,程序就会进行强制转换
函数的声明
说了那么多函数的作用,我们来说说函数如何声明
一个最普通的函数包含两个部分,一个是声明部分,另一个是实现的部分。声明相当于告诉计算机 : 我要定义一个函数
int MyFunction();能够在其他函数内声明,如
int **in()
{
int MyFunction();
}
而且不会报错,但是绝对不要这样写,这样写出来的话极其容易出错 ( 所以写写这一段的作用是什么... )
声明函数时,如果只是声明它,那就是没有用的,例如
int MyFunction();
int **in()
{
cout<<MyFunction()<<endl;
//输出MyFunction返回的值
}
因为我们只是声明了有一个函数叫做 MyFunction,而没有具体的实现操作,就像有个投币的按钮,但是它没有任何的操作去实现投币这个动作,那么即使你点了投币这个按钮也不会有什么事发生
一本通平台的讲解
1150 - 1157,1397 - 1413
因为递归是一个算法,所以这里先不对它进行讲解
1150:求正整数2和n之间的完全数
#include<iostream>
using namespace std;
bool number(int x)
{
int i,sum=0;//这里与外界隔绝,所以也可以使用变量i
for(i=1;i<=x/2;i++) if(x%j==0) sum=sum+j;//较大的因子为x/2,所以只用到x/2
if(sum==x) return true;//如果相等就返回true
else return false;//否则就返回false
}
int **in()
{
int i,n;
cin>>n;
for(i=2;i<=n;i++) if(number(i)) cout<<i<<endl;//从2-n输出所有完全数
return 0;
}
其中的 number 函数返回来之后,就到了 if 中,经过 if 的判断决定是否输出
1151:素数个数
#include<iostream>
#include<c**th>
using namespace std;
int prime(int x)
{
if(x<2) return false;
for(int i=2;i<=sqrt(x);i++) if(x%i==0) return 0;//判断是否为素数
return 1;
}
int **in()
{
int i,n,sum=0;
cin>>n;
for(i=2;i<=n;i++) sum+=prime(i);//如果它是素数,prime会返回1,sum就加上1
cout<<sum<<endl;//输出
return 0;
}
其中 sum 加上 prime 函数返回的值后就可以做到
1152:较大数**x(x,y,z)
#include<iostream>
#include<cstdio>
using namespace std;
int **xn(int x,int y,int z)
{
return **x(x,**x(y,z));//利用**x函数找到三个数中的较大数
}
int **in()
{
int a,b,c;
cin>>a>>b>>c;
printf("%.3lf\n",**xn(a,b,c)/(**xn(a+b,b,c)***xn(a,b,b+c)*1.0));
//按照公式输出即可
return 0;
}
在原题中也给出了函数的定义,其实就是 **x 函数的升级版,能够找出 3 个数当中较大的数罢了
1153:绝对素数
这道题需要交换两位数个位和十位上的数字,我们需要分离个位和十位的公式为,假设为 n
个位=n%10
十位=n/10
这样,我们就可以分离个位和十位了
#include<iostream>
#include<c**th>
using namespace std;
bool prime(int x)
{
if(x<2) return false;
for(int i=2;i<=sqrt(x);i++) if(x%i==0) return false;//判断是否为素数
return true;
}
int **in()
{
int i;
for(i=10;i<=99;i++) if(prime(i)&&prime(i%10*10+i/10)) cout<<i<<endl;
//如果本身是素数(prime(i))并且将交换个十位后仍然是素数prime(i%10*10+i/10)
return 0;
}
分离后判断即可
1154:亲和数
#include<iostream>
using namespace std;
int affinity(int x)
{
int i,sum=0;
for(i=1;i<=x/2+1;i++) if(x%i==0) sum=sum+i;//计算因子之和
return sum;
}
int **in()
{
int i;
for(i=1;;i++)
{
if(i==affinity(affinity(i))&&i!=affinity(i))//如果因子之和互相相等
{
cout<<i<<' '<<affinity(i)<<endl;//输出
break;
}
}
return 0;
}
判断亲和数再输出即可
1155:回文三位数
三位数的回文判断只需判断百位和个位是否相等即可
假设 n
个位=n%100
十位=n/10%10
百位=n/100
分离个十百位的方法如上
#include<iostream>
#include<c**th>
using namespace std;
bool prime(int x)
{
if(x<2) return false;
for(int i=2;i<=sqrt(x);i++) if(x%i==0) return false;//判断是否为素数
return true;
}
int **in()
{
int i,n;
for(i=100;i<=999;i++) if(prime(i)&&i/100==i%10) cout<<i<<endl;
//是素数且回文的数字就输出
return 0;
}
1156:求π的值
这道题就是按照给出的公式进行计算就很简单了
#include<iostream>
#include<cstdio>
#include<c**th>
using namespace std;
double Pi(double x)
{
double sum=0,molecular=x,denominator=1;
while(fabs(molecular/denominator)>=1e-6)
//如果这一次产生的值大于1e-6也就是1的-6次方,就停止循环
//fabs()是求绝对值函数,与abs不同的是,它可以求浮点数的绝对值
{
sum+=molecular/denominator;//将每次的和记录在sum当中
molecular=-1*x*x*molecular;//每次控制符号以及分母上的值
denominator+=2;//分子每次增加2
}
return sum;//返回最终结果
}
int **in()
{
printf("%.10lf\n",6*(Pi(1.0/sqrt(3.0))));//按照公式求
return 0;
}
1157:哥德巴赫猜想
#include<iostream>
#include<c**th>
using namespace std;
bool primes[100];
bool prime(int x)//判断素数
{
if(x<2) return false;
for(int i=2;i<=sqrt(x);i++) if(x%i==0) return false;
return true;
}
int **in()
{
int i,j;
for(i=2;i<=100;i++) if(prime(i)) primes=true;//找到1-100中所有素数
for(i=6;i<=100;i+=2)//从6开始,每次增加2,就是取偶数
{
cout<<i<<'=';//预先输出(因为一定可以被拆分)
for(j=1;j<=i;j++)
{
if(primes[j]&&primes[i-j])
//如果j是素数并且i-j也是素数的话,就是i是j和i-j两个素数之和的话
{
cout<<j<<'+'<<i-j<<endl;//输出这两个数
break;
}
}
}
return 0;
}
先利用桶的思想存放所有素数,在进行判断会大大提升效率
1397:简单算术表达式求值
#include<iostream>
using namespace std;
int operation(int x,char y,int z)
{
if(y=='+') return x+z;//如果是加法
if(y=='-') return x-z;//如果是减法
if(y=='*') return x*z;//如果是乘法
if(y=='/') return x/z;//如果是除法
if(y=='%') return x%z;//如果是模 (法...)
}
int **in()
{
int a,b;
char c;
cin>>a>>c>>b;//输入两个数和一个字符
cout<<operation(a,c,b)<<endl;//进行判断
return 0;
}
这主要是考验判断运算符和运算,很简单
1398:短信计费
#include<iostream>
#include<cstdio>
using namespace std;
int sum=0;
int cost(int x)//判断计费,没什么好讲的,都非常基本
{
if(x<=70) sum=sum+1;
else
{
if(x%70!=0) sum=sum+1;
sum=sum+x/70;
}
return sum;
}
int **in()
{
int i,n,a;
float s=0;
cin>>n;
for(i=1;i<=n;i++)
{
cin>>a;
s=cost(a)*0.1;//返回后要乘以0.1
}
printf("%.1f\n",s);//输出
return 0;
}
这道题很简单,过
1399:甲流病人初筛
这道题也是十分简单的
#include<iostream>
#include<cstring>
#include<string>
using namespace std;
string name;
bool filter(float y,int z)
{
if(y>=37.5&&z==1) return true;//体温和症状如果都符合,就返回true
else return false;//否则返回false
}
int **in()
{
float t;
int k,n,i,sum=0;
cin>>n;
for(i=1;i<=n;i++)
{
cin>>name>>t>>k;
if(filter(t,k))//这里并不一定要把名字也传输进去,因为里面的判断不需要用到名字
{
cout<<name<<endl;//是则输出名字
sum++;//累计人数
}
}
cout<<sum<<endl;//输出人数
return 0;
}
1400:统计单词数
找再加即可完成
#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
string a,b,s;
int sum,first;
void finds(int x,int y)
//void类型,不会返回任何东西,但能够对全局变量进行改变
//不能使用find,因为find是一个内置函数,如果它们的名字相同,编译器就不知道用哪个find了
{
if(a==s)//如果与a相同的话
{
sum++;//增加总数
if(sum==1) first=x-y;//如果这是第一个,保存位置
}
s="";//清空串
}
int **in()
{
getline(cin,a);
getline(cin,b);
int i,r=a.size(),l=b.size();
for(i=0;i<r;i++) if(a>='A'&&a<='Z') a+=32;
for(i=0;i<l;i++) if(b>='A'&&b<='Z') b+=32;//全部转换为小写,好判断
for(i=0;i<l;i++)
{
if(b!=' ') s+=b;//没遇上空格时将此位字符塞入s中
else finds(i,r);//一些功能,虽然不使用函数也行(说不定还更简单...)
}
if(sum==0) cout<<-1<<endl;//如果没有找到则输出-1
else cout<<sum<<' '<<first<<endl;//否则输出找到的个数以及第一次出现的地方
return 0;
}
1401:机器翻译
#include<iostream>
#include<cstring>
using namespace std;
int memory[1000000],m,n,a,sum;
void place(int x)
{
for(int i=0;i<m;i++) if(memory==x) return;//如果内存中有这个单词
memory[a]=x;//否则就将单词添加进第a个中
a++;sum++;//增加a和查找单词次数
if(a==m) a=0;//如果a与m相等了,就是填充的位置超出了接线,就将a复位为0
}
int **in()
{
memset(memory,-1,sizeof(memory));
//这个地方非常坑,题目并没有给出下限为0,这个地方会导致第9个点过不去
//不要问我为什么知道是第9个点...
bool flag;
int i,j,x;
cin>>m>>n;
for(i=1;i<=n;i++)
{
cin>>x;//输入
place(x);//翻译
}
cout<<sum<<endl;
return 0;
}
这里不难,但是有单词 0 就很坑
1402:Vigenère密码
Vigenère密码表
代码如下
#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
string key,word;
int **in()
{
getline(cin,key);
getline(cin,word);
int i,j,l=key.size(),r=word.size();
for(i=0;i<l;i++) if(key>='a'&&key<='z') key-=32;//转换为大写,方便计算
for(i=0,j=0;i<r;i++)
{
if(word>='A'&&word<='Z')
{
word=word-(key[j]-65);//对字符进行移位
j++;
if(word<'A') word='Z'-(65-word)+1;
//如果移位超出了范围则进行控制范围
}
else
{
word=word-(key[j]-65);
j++;
if(word<'a') word='z'-('a'-word)+1;
}
if(j>l-1) j=0;//对密钥的控制变量j超出范围做处理
}
cout<<word<<endl;//输出较后的结果
return 0;
}
这种密码就是对字符串进行移位处理,较后输出
1403:素数对
#include<iostream>
#include<c**th>
using namespace std;
bool prime(int x)//判断素数
{
if(x<2) return false;
for(int i=2;i<=sqrt(x);i++) if(x%i==0) return false;
return true;
}
int **in()
{
int i,n;
cin>>n;
for(i=3;i<=n;i++) if(prime(i)&&prime(i+2)) cout<<i<<' '<<i+2<<endl;
//如果i和i+2都是素数的话,这就是一对素数对
return 0;
}
判断素数是非常常用的,所以一定要记住怎么判断
1404:我家的门牌号
这道题可以使用暴力的方法去做
#include<iostream>
using namespace std;
int Sum(int n)
{
int i,sum=0;
for(i=1;i<=n;i++) sum+=i;
return sum;
}
int **in()
{
int i,j,n,sum;
cin>>n;
for(i=1;;i++)//枚举户数
{
sum=Sum(i);//计算在有i户时
for(j=1;j<=i;j++)//枚举我家的门牌号
{
if(sum-3*j==n)
{
cout<<j<<' '<<i;//符合则输出
return 0;
}
}
}
return 0;
}
1405:质数的和与积
这题同样使用暴力解决
#include<iostream>
#include<c**th>
using namespace std;
bool prime(int x)//判断素数(又是它...)
{
if(x<2) return false;
for(int i=2;i<=sqrt(x);i++) if(x%i==0) return false;
return true;
}
int **in()
{
int i,n,**xn=-1;
cin>>n;
for(i=2;i<=n;i++) if(prime(i)&&prime(n-i)) **xn=**x(**xn,i*(n-i));
//如果i和n-i都是素数,我们就取它们的积,然后判断是否大于较大值
cout<<**xn<<endl;//输出
return 0;
}
1406:单词替换
#include<iostream>
#include<string>
using namespace std;
string a,b,c;
int **in()
{
getline(cin,a);//输入原文
getline(cin,b);//输入待替换词
getline(cin,c);//输入替换词
int i,l=a.size(),r=b.size();
for(i=0;i<l;i++)
{
if(a.substr(i,r)==b)//如果符合替换的要求
{
cout<<c;//输出
i+=r-1;//跳过这一部分的单词
}
else cout<<a;//如果不是就按照原文输出
}
return 0;
}
判断后输出即可
1407:笨小猴
这道题可以利用我们之前学的桶计数的方法解决
#include<iostream>
#include<cstdio>
#include<c**th>
using namespace std;
int t[26];
string a;
bool prime(int x)//判断素数
{
if(x<2) return false;
for(int i=2;i<=sqrt(x);i++) if(x%i==0) return false;
return true;
}
int **in()
{
getline(cin,a);
int i,**xn=0,minn=1000,l=a.size();
for(i=0;i<l;i++) t[a-'a']++;//桶计每个字符出现的次数
for(i=0;i<26;i++)//判断每一个字符
{
if(t>**xn) **xn=t;//如果大于较大值
if(t<minn&&t!=0) minn=t;
//如果小于**小值,这里好需要判断其不等于0,因为0是不能作为**小值出现的
}
if(prime(**xn-minn)) cout<<"Lucky Word"<<endl<<**xn-minn<<endl;//是素数
else cout<<"No Answer"<<endl<<0<<endl;//不是素数
return 0;
}
1408:素数回文数的个数
这里需要判断素数以及回文数,素数我们会判断了,那回文数怎么判断
#include<iostream>
#include<c**th>
using namespace std;
bool prime(int x)//判断素数
{
if(x<2) return false;
for(int i=2;i<=sqrt(x);i++) if(x%i==0) return false;
return true;
}
bool palindrome(int x)//判断回文
{
int sum=0,a=x;
while(x>0)//判断结束
{
sum=sum*10+x%10;//将sum的值改为上一次的sum*10再加上x%10
x/=10;//x除以10
//这整一个流程就是先将x的较低位取出来放在sum中,再将x除以10,去掉个位
//再次进行这样的流程直到x为0,就可以将x这个数反过来了
}
if(sum==a) return true;//判断是否为原数
else return false;
}
int **in()
{
int i,n,sum=0;
cin>>n;
for(i=11;i<=n;i++) if(prime(i)&&palindrome(i)) sum++;//判断素数和回文
cout<<sum<<endl;
return 0;
}
判断的回文数过程 :
x = 123 , sum = 0
x = 12 , sum = 3
x = 1 , sum = 32
x = 0 , sum = 321
1409:判决素数个数
这题要比上一题简单,只需判断素数即可
#include<iostream>
#include<c**th>
using namespace std;
int prime(int x)//判断素数
{
if(x<2) return false;
for(int i=2;i<=sqrt(x);i++) if(x%i==0) return false;
return true;
}
int **in()
{
int i,x,y,sum=0;
cin>>x>>y;//从x到y
for(i=x;i<=y;i++) if(prime(i)) sum++;//满足则增加sum
cout<<sum<<endl;
return 0;
}
1410:较大质因子序列
这题也很简单,只不过需要多判断一些数罢了
#include<iostream>
#include<c**th>
using namespace std;
bool prime(int x)//判断素数
{
if(x<2) return false;
for(int i=2;i<=sqrt(x);i++) if(x%i==0) return false;
return true;
}
int **in()
{
int m,n,i,j;
cin>>m>>n;
for(i=m;i<=n;i++)//从m到n
{
for(j=i;j>=2;j--)//从i往下找较大质因子
{
if(i%j==0&&prime(j))//满足条件
{
cout<<j;//输出
if(i!=n) cout<<',';//不是较后一个就要输出逗号
break;
}
}
}
cout<<endl;
return 0;
}
1411:区间内的真素数
这题的真素数就是回文后仍然是素数的素数
#include<iostream>
#include<c**th>
using namespace std;
int palindrome(int x)//返**文数,与上面一样
{
int sum=0;
while(x>0)
{
sum=sum*10+x%10;
x/=10;
}
return sum;
}
bool prime(int x)//判断素数
{
if(x<2) return false;
for(int i=2;i<=sqrt(x);i++) if(x%i==0) return false;
return true;
}
int **in()
{
int m,n,i;
bool flag=false;
cin>>m>>n;
for(i=m;i<=n;i++)
{
if(prime(i)&&prime(palindrome(i)))//判断素数和回文素数是否都成立
{
if(flag) cout<<',';//是则输出
cout<<i;
flag=true;
}
}
if(!flag) cout<<"No"<<endl;//否则输出"No"
return 0;
}
1412:二进制分类
这里虽然有二进制,但不一定要使用进制转化使它成为为二进制
#include<iostream>
using namespace std;
bool binary(int x)
{
int a=0,b=0;
while(x>0)
{
if(x%2) a++;//在十进制中,如果对其模2为1就说明其对应的二进制数较后一位为1
else b++;//否则就是0
x/=2;//每次除以2
}
return a>b;//判断是A类还是B类数
}
int **in()
{
int a=0,b=0,i;
for(i=1;i<=1000;i++)
{
if(binary(i)) a++;//如果是a类则a增加
else b++;//否则就是b类
}
cout<<a<<" "<<b<<endl;//输出a和b类的数量
return 0;
}
1413:确定进制
这道题就要运用到进制转换了,进制转换的方法是非常重要的
#include<iostream>
#include<c**th>
using namespace std;
int convert(int base,int x)//十进制转N进制的方法
{
int sum=0,n=0;//sum:较后的值,n:位数
while(x)
{
sum+=x%10*pow(base,n);//反向提取较后一位并乘以进制的位数次方
x/=10;//将x的较后一位去除
n++;//位数增加
}
return sum;
}
int **in()
{
int i,p,q,r;
cin>>p>>q>>r;
for(i=2;i<=40;i++)//从2到40
{
if(convert(i,p)*convert(i,q)==convert(i,r))//判断是否满足
{
cout<<i<<endl;//满足则输出
return 0;
}
}
cout<<0<<endl;//否则输出0
return 0;
}
好了,题目都讲完了,相信你已经懂了吧
文档下载
转载:感谢您阅览,转载请注明文章出处“来源从小爱孤峰知识网:一个分享知识和生活随笔记录的知识小站”。
链接:C++ 函数讲解与一本通平台讲解http://www.gufeng7.com/niaolang/1851.html
联系:如果侵犯了你的权益请来信告知我们删除。邮箱:119882116@qq.com
上一篇: C++ 数组一本通平台讲解
下一篇: C++ 算法