C++函数

C++函数

1.基本工作

  • 提供函数的定义,及实现
  • 提供函数的原型 //必须的,为了提高编译器的执行效率!可以省略函数名,或者直接将函数定义放在main前
	//作用
//1.编译器能够正确的处理函数返回值
//2.编译器能够检查使用的参数数目是否正确
//3.编译器检查使用的参数类型是否正确
  • 调用函数

2.函数种类

  • 有返回值函数
//C++不能直接返回数组,只能返回整型,浮点型,char,string型,指针,对象,结构,返回类型不一致将发生强制类型转换!!
  • 无返回值函数,即void

3.函数参数传递

  • 按值传递
//
double max(int a){
    return a;
}
int b=10;
max(b);//调用时,按值传递,该函数将创建一个临时变量a,初始化为10,进行传入,操作的只是b的副本,对b无法修改,使用引用传递,有修改的风险,可设置为const常量引用!!
double max(const int &a){
	return a;
}
max(b);
  • 引用传递

3.1传入数组参数

传入方法:

	//方法一:传入数组名
int sum(int arr[],int n);//表示传入n长度的数组参数
//调用
int a1[]={2,4,5,7,3};
sum(a1,5);//这里函数名相当于一个指向数组的指针

	//方法二:传入数组指针
int sum(int *arr,int n);//表示传入n长度的数组参数,这里输入的sizeof arr只是一个指针长度8字节
//调用
int a1[]={2,4,5,7,3};
sum(a1,5);//这里函数名相当于一个指向数组的指针

	//方法三:传入数组两个区间指针
int sum(int *begin,int *end){
    int total;
	for(int *p=begin;p!=end;p++){
		total+=*p;
    }
    return total;
}
int a1[]={1,2,3,5,6,7,8,9,10};
sum(a1+1,a1+8);//传入1~8区间的数组
	
	//方法四:传入二维数组
int sum(int (*arr)[4],int n);//表示传入一个指向4个元素的数组指针
//or
int sum(int arr[][4],int n);
int a1[3][4]={{1,2,3,4},{35,5,7,8},{5,7,8,9}};
	
//解释,这里传入一个数组,只是将数组的地址和数组长度传入,并没有传入具体的数组内容!!,意味着,实际操作的就是数组本身!!!这跟传入引用和指针效果都是一样的,千万要注意到底要不要修改传入的原本数据值,可以使用const修饰
int sum(const int *arr,int n);

//实例
#include <iostream>
#include <string>
using namespace std;
double max(int arr[],int n){
	cout<<sizeof arr<<"\n";
	int total;
	for (int i=0;i<n;i++){
		total+=arr[i];
	}
	cout<<total<<"\n";
	return total;
}

int main(){
	int a1[10]={1,2,454,65,4,2,6,3,2};
	cout<<sizeof a1<<"\n";
	max(a1,10);
	max(a1,2);
	max(a1+5,5);	//可以选择性传入数组段
}//打印结果 
     /* 40  //数组全部长度a1为40字节
        8   //传入数组指针长度为8字节
        539
        8
        3
        8
        13  */

3.2传入结构参数

//结构体作为参数,传入可以视为单值变量,可以按值传递,或者引用传递,不同的是,结构名不代表地址,必须使用 &结构名,作为结构对象的引用
	//直接值传递
struct book{
	char b_name[20];
    char b_author[10];
    float b_price;
};
book total_price(book b1,book b2){
    book t;
    t.b_price=b1.b_price+b2.b_price;
    return t;
}
book p1={"C++","yang",21.3};
book p2={"java","xu",23.32};
cout<<total_price(p1,p2).b_price;
//输出44.62

	//结构体一般采用,引用传递,节省时间和空间的消耗
book total_price(const book &b1,const book &b2){
    book t;
    t.b_price=b1.b_price+b2.b_price;
    return t;
}
	
	//或者使用传递指针参数
book total_price(const book *b1,const book *b2){
    book t;
    t.b_price=b1->b_price+b2->b_price;//这时只能使用指针间接成员运算符->访问
    return t;
}
book p1={"C++","yang",21.3};
book p2={"java","xu",23.32};
cout<<total_price(&p1,&p2).b_price;//将地址传递给指针参数

3.3传入类–对象参数

3.4传入函数指针参数

3.5传入字符串参数

	//方法一:直接传入一个string类引用对象
int m_num(const string &s);
string s1="yangmfddmmdfmm";
m_num(s1);

	//方法二:传入字符串首地址
char m1[15]="gsdgdmgdmdgmgm";
char *m2="gsdmgmdmdmsmsdmf";
int m_num(const char *c){
 	cout<<*c; 
    return 0;
}
m_num(m1);
m_num(m2);

4.函数的递归操作

4.1含有一个递归调用的递归

//形如:
void recursion(argument1){
    statements1
    if(test)
        recursion(argument2)
    statements2
}
//表示函数自己调用自己,这样将无限循环下去,必须将递归调用置于一个边界条件下,为false时,递归调用结束
//只要if为true时,调用recursion,都会执行statements1,不会执行statements2,
//只要if为false时,就会执行statements2,然后结束,并将控制权返回给前一个调用!!
//因此,如果recursion调用了5次,则statements1执行了5次,之后statements2与函数调用相反的顺序执行5次,从而调用结束!!!

//实例
void test(int n){
	cout<<"this level n="<<n<<"\t"<<&n<<"\n";
    if(n>0)
        test(n-1);
    cout<<"this rather level n="<<n<<"\t"<<&n<<"\n";
}
int main(){
	test(4);
}
//输出:
/*
    this level n=4  0x71fe30
    this level n=3  0x71fdf0
    this level n=2  0x71fdb0
    this level n=1  0x71fd70
    this level n=0  0x71fd30
    this rather level n=0   0x71fd30  //可以看出每次调用函数都会创建占用不同的内存
    this rather level n=1   0x71fd70  //但是同一次调用,函数内的变量占用相同首地址的内存
    this rather level n=2   0x71fdb0
    this rather level n=3   0x71fdf0
    this rather level n=4   0x71fe30
*/

4.2包含多个递归调用的递归

//主要采用分而治之的思想,将一个大问题逐渐分解成两到三个小相同的问题,再细分,直到能解决问题为止
//如:汉诺塔的问题,将n块铁饼,在保证不扰乱高低顺序情况下,将n块通过塔p2,移动至塔p3
void move(char c1,char c2){
    cout<<c1<<"->"<<c2<<"\n";	
}
void hanoi(int n,char one,char two,char three){//大问题是将n块从塔1借助塔2,移到塔3
	if(n==1){
		move(one,three);
    }else{
		hanoi(n-1,one,three,two);//小问题是先将n-1块从塔1借助,塔3移到塔2
        move(one,three);  //移动塔1剩余的一块
        hanoi(n-1,two,one,three);//再将n-1块从塔2借助塔1,移动到塔3 ,大问题就解决了!
    }
}
int main(){
	hanoi(3,'A','B','C');
}//输出如下:
	/*	A->C
        A->B
        C->B
        A->C
        B->A
        B->C
        A->C
     */   
//缺点:由于调用一次产生2个调用,2个产生4个,4个产生8个,n次调用产生2^n个,成指数级增长,可见时间及空间的消耗是巨大的!!

4.3尾递归调用

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值