从零开始学习C++第四篇:函数和函数模板

一、函数的参数及其传递方式

1、形参与实参

形参:形式参数。就是定义函数的时候,写在函数名小括号后面的参数叫形参。

实参:实际参数。就是调用函数的时候,调用函数时写在函数名小括号后面的参数就叫实参

https://www.cnblogs.com/jialiangliang/p/6011793.html

2、传递参数的三种方式

2.1对象作为函数参数

将实参对象的值传给形参对象,形参有实参的备份,当函数改变形参时,改变的是备份的值,不会影响原来实参的值。

可以防止被调用的函数改变参数的原始值。

#include <iostream>
#include<string>
using namespace std;
void swap(string,string);
int main() {
	string str1="hello",str2="world";
	swap(str1,str2);
	cout<<str1<<" "<<str2<<endl;
	return 0;
}
void swap(string a,string b){  //交换str1和str2的值并输出,但不影响str1和str2原先的值
	string temp;
	temp=a;a=b;b=temp;
	cout<<a<<" "<<b<<endl;
}

运行结果:

world hello
hello world

2.2对象指针作为函数参数

形参是对象指针,实参是兑现的地址值。因为形参与实参地址相同,所以改变形参就是改变实参。

#include <iostream>
#include<string>
using namespace std;
void swap1(string,string);
void swap2(string *,string *);//形参是string类的指针
int main() {
	string str1="hello",str2="world";
	//swap1(str1,str2);
	swap2(&str1,&str2);    //传入的是字符串的存储地址
	cout<<str1<<" "<<str2<<endl;
	return 0;
}
void swap1(string a,string b){  //交换str1和str2的值并输出,但不影响str1和str2原先的值
	string temp;
	temp=a;a=b;b=temp;
	cout<<a<<" "<<b<<endl;
}
void swap2(string *a,string *b){  //
	string temp;
	temp=*a;*a=*b;*b=temp;
	cout<<*a<<" "<<*b<<endl;
}

运行结果:

world hello
world hello

2.3引用作为函数参数

在函数调用时,实参对象名传给形参对象名,形参对象名就是实参对象名的别名。实参对象和形参对象代表同一个对象,改变形参对象就是改变实参对象的值。

C++中int、int&、int*和int**的区别与联系、用途  http://blog.csdn.net/nbadwde/article/details/60466811

#include <iostream>
#include<string>
using namespace std;
void swap1(string,string);//对象作为函数参数
void swap2(string*,string*);//对象指针作为函数参数,形参是string类的指针
void swap3(string&,string&);//引用作为函数参数   这里的&不是取址符号,而是引用符号
int main() {
	string str1="hello",str2="world";
	//swap1(str1,str2);
	//swap2(&str1,&str2);    //传入的是字符串的存储地址
	swap3(str1,str2);
	cout<<str1<<" "<<str2<<endl;
	return 0;
}
void swap1(string a,string b){  //交换str1和str2的值并输出,但不影响str1和str2原先的值
	string temp;
	temp=a;a=b;b=temp;
	cout<<a<<" "<<b<<endl;
}
void swap2(string *a,string *b){  //string类的对象指针a和b作为函数参数
	string temp;
	temp=*a;*a=*b;*b=temp;
	cout<<*a<<" "<<*b<<endl;
}
void swap3(string &a,string &b){  //string类的引用对象a和b作为函数参数
	string temp;                  //形参 a b 和实参 str1 str2 在同一个单元  传引用不单独占用内存单元
	temp=a;a=b;b=temp;            //而传指针要开辟内存单元 
	cout<<a<<" "<<b<<endl;
}

运行结果:

world hello
world hello

间接引用数组,求10个学生的平均分,并统计不及格人数。

#include <iostream>
using namespace std;
typedef double array[12];//自定义数组标识符 array  多出的两个格子填人数和平均分
void avecount(array& b,int n){//一个参数使用引用,一个参数使用对象
	double ave=0;
	int count=0;
	for(int i=0;i<(n-2);i++){
		ave=ave+b[i];
		if(b[i]<60){
			count++;
		}
	}
	b[11]=ave/(n-2);
	b[12]=count;
}
int main() {
//	 float a[10]={23.6,69.7,58.2,96,65,12,2,78,65,100};
//	int f=0;
//	float avg=0,sum=0;
//	for(int i=0;i<10;i++){
//		sum=sum+a[i];
//		if(a[i]<60){
//			f++;
//		}
//	}
//	avg=sum/10;
//	cout<<"平均分为:"<<avg<<" 不及格人数为:"<<f<<endl;

	array b={23.6,69.7,58.2,96,65,12,2,78,65,100};
	array &a=b;       //间接引用数组 a是b的引用
	avecount(a,12);   //参数是b的引用  所以传入的是a  调用函数统计 计算
	cout<<"平均分为:"<<b[11]<<" 不及格人数为:"<<b[12]<<endl;

	return 0;
}

运行结果:

平均分为:56.95 不及格人数为:4

3、用const保护数据

#include <iostream>
using namespace std;
void change(const string&);//函数形参也要用const修饰
int main() {
	const string str1="hello";
	change(str1);
	cout<<str1<<endl;
	return 0;
}
void change(const string& a){
	//a=a+" world!";  在函数内只能使用,不能修改
	string b=a+" world!";
	cout<<b<<endl;
}
运行结果:
hello world!
hello

二、函数的返回值类型

C++函数的返回值可以是除数组和函数以外的任何类型。

返回指针的函数

函数的返回值为存储某个变量的地址,这种函数为指针函数,一般定义   类型标识符  *函数名(参数列表);

/*使用函数input()输入一组数,并返回一个指针,然后用main()函数显示*/
#include <iostream>
using namespace std;
int *input(int&);
int main() {
	int num;
	int *data;//定义与buf类型一样的指针
	data=input(num);
	if(data){  //data不为空 
	for(int i=0;i<num;i++){
		cout<<data[i]<<" ";
	}
	delete data;  //释放内存空间
	}
	return 0;
}

int *input(int& a){
	cout<<"输入数字个数";
	cin>>a;  //a是主函数变量num的引用
	if(a<0){  //如果输入不合理
		return NULL;
	}
	int *buf=new int[a];//分配a个int型数据的存储空间
	if(buf==0){   //如果没有申请到内存空间
		return NULL;
	}
	for(int i=0;i<a;i++){
		cin>>buf[i];  //将输入的值存入指定地址
	}
	return buf; //返回指针
}

运行结果:

输入数字个数3
3
6
9
3 6 9

返回对象的函数

#include <iostream>
using namespace std;
string str(const int);
int main() {
	int num;
	cout<<"输入字符串个数"<<endl;
	cin>>num;
	cout<<str(num);
	return 0;
}
string str(const int a){
	string str1,str2;
	for(int i=0;i<a;i++){
		cin>>str1;
		str2=str2+str1+" ";
	}
	return str2;
}

运行结果:

输入字符串个数
2
hello
world!
hello world! 

很简单。

函数返回值作为函数参数

如果返回值作为参数,那么返回值类型必须与函数类型一致。

/*比较三个数大小,函数返回值作为参数*/
#include <iostream>
using namespace std;
int max1(int,int);
//int max2(max1(int,int),int,int);
int main() {
cout<<max1(max1(45,36),96);
	return 0;
}
int max1(int a,int b){
//	if(a>b){
//		return a;
//	}else{
//		return b;
//	}
	return (a>b)?a:b;
}
//int max2(int a,int b,int c){
//	int d=max1(a,b);
//	return max1(d,c);
//}

运行结果:

96

内联函数

用关键字inline说明的函数称为内联函数。具有循环语句和switch语句的都是内联函数,内联函数一般很短,在第一次调用之前必须声明。

#include <iostream>
using namespace std;
inline int isnumber(char c){return (c>='0'&&c<='9')?1:0;}
int main() {
	char a;
	cout<<"输入一个字符"<<endl;
	cin>>a;
	if(isnumber(a)){
		cout<<"是数字";
	}else{
		cout<<"不是数字";
	}
	return 0;
}

函数重载和默认函数

函数重载可使一个函数名具有多种功能,即具有多种形态,称这种特性为多态性。

函数重载产生多态性的例子。

#include <iostream>
using namespace std;
int max(int,int);
double max(double,double);
char max(char,char);
int max(int,int,int);
int main() {
	cout<<max(5,6)<<endl;
	cout<<max(5,6,7)<<endl;
	cout<<max(5.3,6.6)<<endl;
	cout<<max('a','b')<<endl;
	return 0;
}
int max(int a,int b){
	return (a>b)?a:b;
}
int max(int a,int b,int c){
	return (max(a,b)>c)?max(a,b):c;
}
double max(double a,double b){
	return (a>b)?a:b;
}
char max(char a,char b){
	return (a>b)?a:b;
}

运行结果:

6
7
6.6
b

函数模板

#include <iostream>
using namespace std;
//template <class T>
template <typename T>//用typename代替class
	T max1(T m1,T m2){
		return (m1>m2)?m1:m2;
	}
template <typename T>//必须重写
	T min1(T m1,T m2){
		return (m1<m2)?m1:m2;
	}
int main() {
	cout<<max1(8.6,double(7));
	return 0;
}

输出结果:

8.6

求方程ax²+bx+c=0的根

#include <iostream>
#include<math.h>
using namespace std;
void puths(int,int,int);
void jg(int,int,int);
void puths(int a,int b,int c){
	if(b>0){
			if(c>0){
				cout<<"方程式为"<<a<<"x²+"<<b<<"x+"<<c<<"=0"<<endl;
			}
			if(c<0){
				cout<<"方程式为"<<a<<"x²+"<<b<<"x"<<c<<"=0"<<endl;
			}
		}
		if(b<0){
			if(c>0){
				cout<<"方程式为"<<a<<"x²"<<b<<"x+"<<c<<"=0"<<endl;
			}
			if(c<0){
				cout<<"方程式为"<<a<<"x²"<<b<<"x"<<c<<"=0"<<endl;
			}
		}
}
void jg(int a,int b,int c){
	float temp,x1,x2;
	temp=b*b-4*a*c;
	if(temp>0){
			x1=(-b+sqrt(temp))/2*a;
			x2=(-b-sqrt(temp))/2*a;
			cout<<"x1="<<x1<<"  x2="<<x2<<endl;
		}
		if(temp==0){
			x1=b/2*a;
			x2=-b/2*a;
			cout<<"x1="<<x1<<"  x2="<<x2<<endl;
		}
		if(temp<0){
			cout<<"该方程无解。"<<endl;
		}
}
int main() {
	int a,b,c;
//	float x1,x2;
	cout<<"输入a、b、c的值,以空格隔开"<<endl;
	cin>>a>>b>>c;
	puths(a,b,c);
	jg(a,b,c);
//	if(b>0){
//		if(c>0){
//			cout<<"方程式为"<<a<<"x²+"<<b<<"x+"<<c<<"=0"<<endl;
//		}
//		if(c<0){
//			cout<<"方程式为"<<a<<"x²+"<<b<<"x"<<c<<"=0"<<endl;
//		}
//	}
//	if(b<0){
//		if(c>0){
//			cout<<"方程式为"<<a<<"x²"<<b<<"x+"<<c<<"=0"<<endl;
//		}
//		if(c<0){
//			cout<<"方程式为"<<a<<"x²"<<b<<"x"<<c<<"=0"<<endl;
//		}
//	}

//	float temp=b*b-4*a*c;
//
//	if(temp>0){
//		x1=(-b+sqrt(temp))/2*a;
//		x2=(-b-sqrt(temp))/2*a;
//		cout<<"x1="<<x1<<"  x2="<<x2<<endl;
//	}
//	if(temp==0){
//		x1=-b/2*a;
//		x2=b/2*a;
//		cout<<"x1="<<x1<<"x2="<<x2<<endl;
//	}
//	if(temp<0){
//		cout<<"该方程无解。"<<endl;
//	}
	//cout<<"方程式为"<<a<<"x²+"<<b<<"x+"<<c<<"=0"<<endl;
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值