NOIP学习小站
西安交通大学附属中学航天学校

自定义函数例题

一、打印字符三角形

打印边长为\(n\)由字符\(ch\)组成的三角形。用函数实现,很显然函数没有返回值,有两个参数:int类型的参数n,表示字符三角形边长;char类型的参数ch,表示组成三角形的字符:

#include<iostream>
using namespace std;
void print(int n,char ch){
	for(int i=1;i<=n;i++){
		for(int j=1;j<=i;j++) cout<<ch;
		cout<<endl;
	}
} 
int main()
{
	print(10,'@');
	print(5,'#');
	int m;
	char c;
	cin>>m>>c;
	//实际参数变量名和形式参数名不必相同
	print(m,c); 
    return 0;
}

需要额外注意的是,调用函数时,如果实际参数是变量,那么实际参数变量名不必和函数的形式参数相同。

如果不使用函数,可以预见程序中会重复出现相同或相似的代码,让整个程序显得臃肿繁琐:

#include<iostream>
using namespace std;
int main()
{
	for(int i=1;i<=10;i++){
		for(int j=1;j<=i;j++) cout<<'@';
		cout<<endl;
	}
	
	for(int i=1;i<=5;i++){
		for(int j=1;j<=i;j++) cout<<'#';
		cout<<endl;
	}
	
	int m;
	char c;
	cin>>m>>c;
	for(int i=1;i<=m;i++){
		for(int j=1;j<=i;j++) cout<<c;
		cout<<endl;
	}
    return 0;
}

如果我们将print函数定义语句放到main函数的后面,会发生编译错误:

#include<iostream>
using namespace std;
int main()
{
    print(10,'@');    //会发生编译错误
    return 0;
}
void print(int n,char ch){
    for(int i=1;i<=n;i++){
        for(int j=1;j<=i;j++) cout<<ch;
        cout<<endl;
    }
} 

其实我们可以将自定义函数定义语句放到main函数的后面,此时需要在main函数前申明自定义函数,最简单的做法就是将自定义函数的函数头拷贝到main函数前:

#include<iostream>
using namespace std;
void print(int n,char ch);   //申明函数(注意语句结尾处的分号) 
int main()
{
    print(10,'@'); 
    return 0;
}
void print(int n,char ch){
    for(int i=1;i<=n;i++){
        for(int j=1;j<=i;j++) cout<<ch;
        cout<<endl;
    }
} 

二、计算最大值

计算两个int整数\(x\)和\(y\)的最大值。用函数实现,很显然函数的返回值类型应该设置为int类型,有两个int类型的参数:

#include<iostream>
using namespace std;

int max(int x,int y){
	if(x>y) return x;
	else return y;
}

int main()
{
	cout<<max(1,2)<<endl;
	int a,b;
	cin>>a>>b;
	cout<<max(a,b)<<endl;
    return 0;
}

这里max函数还可以进一步精简:

int max(int x,int y){
	if(x>y) return x;
	return y;
}

函数体中只要运行到return语句就强制结束函数返回到调用处,不会再执行函数体return语句后面的内容。

int max(int x,int y){
	return x>y?x:y;
}

这里使用了条件运算符来精简代码。

三、大写字母转小写

将大写字母转换成对应的小写字母。用函数实现,返回值类型为char,参数类型也是char:

#include<iostream>
using namespace std;

char convert(char ch){
	if(ch>='A' && ch<='Z') return ch+32;
	return ch;
}

int main()
{
	cout<<convert('D')<<endl;
	cout<<convert('$')<<endl;
	char c;
	cin>>c;
	cout<<convert(c)<<endl;
    return 0;
} 

四、判断闰年

判断正整数\(y\)对应年份是否为闰年。用函数实现,可以将函数的返回值设置为bool类型:

#include<iostream>
using namespace std;

bool leap(int y){
	if((y%4==0 && y%100!=0) || y%400==0) return true;
	return false;
}

int main()
{
	int n;
	cin>>n;
	if(leap(n)==true) cout<<"Leap year"<<endl;
	else cout<<"Nonleap year"<<endl;
    return 0;
} 
#include<iostream>
using namespace std;

bool leap(int y){
	return (y%4==0 && y%100!=0) || y%400==0;  //直接返回判断结果
}

int main()
{
	int n;
	cin>>n;
	if(leap(n)) cout<<"Leap year"<<endl;      //==true可以省略
	else cout<<"Nonleap year"<<endl;
    return 0;
} 

五、判断素数

判断正整数\(n\)是否为素数。用函数实现,可以将函数的返回值设置为bool类型:

#include<iostream>
using namespace std;

//判断n是否为素数 
bool isPrime(int n){
	if(n==1) return false;
	
	for(int i=2;i*i<=n;i++){
		if(n%i==0) return false;
	}
	
	return true;
} 

int main()
{
    int m;
    cin>>m;
    if(isPrime(m)) cout<<"YES";
	else cout<<"NO";
    return 0;
}

比较这里的函数和之前不用函数的语句,会发现函数体中巧妙使用return语句强制退出函数可以让程序结构更加精简:

bool isPrime(int n){
	if(n==1) return false;	
	for(int i=2;i*i<=n;i++){
		if(n%i==0) return false;
	}	
	return true;
}
//调用函数
int n;
cin>>n;
if(isPrime(n)){
}
int n;
bool f = true; //标记变量
cin>>n;
if(n==1) f = false;
for(int i=2;i*i<=n;i++){
	if(n&i==0){
		f = false;
		break;
	}
}
if(f){
}

六、计算三角形周长和面积

问题:输入三角形三个顶点的坐标,计算并输出三角形的周长和面积。

#include<iostream>
#include<cmath>
using namespace std; 
//计算平方 
double sq(double x){
	return x*x;
}

//计算两坐标点距离(线段长度)
double dist(double x1,double y1,double x2,double y2){
	return sqrt(sq(x1-x2)+sq(y1-y2));
}

//计算三角形周长
double len(double a,double b,double c){
	return a+b+c;
}

//计算三角形面积
double area(double a,double b,double c){
	double p = len(a,b,c)/2;
	return sqrt(p*(p-a)*(p-b)*(p-c));
}
int main()
{
    double x1,y1,x2,y2,x3,y3;
	cin>>x1>>y1>>x2>>y2>>x3>>y3;
	double a = dist(x1,y1,x2,y2);
	double b = dist(x2,y2,x3,y3);
	double c = dist(x3,y3,x1,y1);
	cout<<len(a,b,c)<<" "<<area(a,b,c)<<endl;
    return 0;
}

很显然,可以在自定义函数中调用其他自定义函数。通过上面的程序代码可以看出,借助自定义函数,main函数的结构变得如此简单清晰,可读性大大提高,这也是使用函数的优势。