一、函数的参数及其传递方式
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;
}