2、函数

1、为什么要用函数

        函数是程序的基本模块,是用于完成特定任务的程序代码单元。

        函数分为系统函数和用户定义函数。系统函数是由编译系统提供,而自定义函数是用户解决专门的需求。

1、函数可以省去重复的代码

#include<iostream>
using namespace std;

int main()
{
    int a = 1, b = 2, c = 3, d = 4;
    int n;

    cout << a << " "<< b<<" " << c << " " << d << endl;

    n = a;
    a = b;
    b = n;

    n = c;
    c = d;
    d = n;
    cout << a << " " << b << " " << c << " " << d << endl;

    return 0;
}
#include<iostream>
using namespace std;

void swap(int &a, int &b)
{
    int temp;
    temp = a;
    a = b;
    b = temp;
}

int main()
{
    int a = 1, b = 2, c = 3, d = 4;
    int n;

    cout << a << " "<< b<<" " << c << " " << d << endl;

    swap(a, b);

    swap(c, d);
    
    cout << a << " " << b << " " << c << " " << d << endl;

    return 0;
}

 使用函数后,降低代码的重复率。

2、函数可以使程序更加模块化,是程序阅读更方便

2.为什么要用函数重载

在实际开发中,有时候我们需要实现几个功能类似的函数。例如希望交换两个变量的值,这两个变量有多种类型,可以是 int、float、char 等,我们需要通过参数把变量的地址传入函数内部。

在C语言中,程序员往往需要分别设计出三个不同名的函数,其函数原型与下面类似:

void swap1(int *a, int *b);     
void swap2(float *a, float *b); 
void swap3(char *a, char *b);    

 而在c++语法中,可以使函数的声明更加方便

void swap(int *a, int *b);      
void swap(float *a, float *b);  
void swap(char *a, char *b);  

函数名相同,根据参数个数不同、类型不同、参数排列顺序不同来判断使用哪一个函数,而函数返回值类型不能判断函数。

#include <iostream>
using namespace std;
void Swap(int &a, int &b) { int temp = a; a = b; b = temp; } void Swap(float &a, float &b) { float temp = a; a = b; b = temp; } void Swap(char &a, char &b) { char temp = a; a = b; b = temp; } int main() { int n1 = 100, n2 = 200; cout<<n1<<", "<<n2<<endl; Swap(n1, n2); cout<<n1<<", "<<n2<<endl; float f1 = 12.5, f2 = 56.93; cout<<f1<<", "<<f2<<endl; Swap(f1, f2); cout<<f1<<", "<<f2<<endl; char c1 = 'A', c2 = 'B'; cout<<c1<<", "<<c2<<endl; Swap(c1, c2); cout<<c1<<", "<<c2<<endl; return 0; }

 

3.什么是值传递

值传递:将实参的值传递对应的形参

 

#include<iostream>
using namespace std;

void swap(int *a, int *b)
{
    int temp;
    temp = *a;
    *a = *b;
    *b = temp;
}
void swap(int a, int b)
{
    int temp;
    temp = a;
    a = b;
    b = temp;
}
int main()
{
    int a = 1, b = 2, c = 3, d = 4;
    int n;

    cout << a << " "<< b<<" " << c << " " << d << endl;

    swap(&a, &b);

    swap(c, d);
    
    cout << a << " " << b << " " << c << " " << d << endl;

    return 0;
}

分析代码:由于形参有自己独立的存储空间,又作为函数的局部变量使用,因此在函数中对任何形参值得修改都不会改变实参变量的值。通过函数swap()函数调用之后,在函数内部将c和d的值交换了,使得swap函数内,c和d的值交换;但是,这个过程并没有改变全局变量a和b的值。

4.什么是地址传递

引用参数是一种特殊的变量,它可以看成变量的别名。

#include<iostream>
using namespace std;

void swap(int &a, int &b)
{
    int temp;
    temp = a;
    a = b;
    b = temp;
}

int main()
{
    int a = 1, b = 2, c = 3, d = 4;
    int n;

    cout << a << " "<< b<<" " << c << " " << d << endl;

    swap(a, b);

    swap(c, d);
    
    cout << a << " " << b << " " << c << " " << d << endl;

    return 0;
}

 值传递与引用传递的区别:

值传递:

函数Swap()被调用前,实参a和b有自己的存储空间,并且有自己的初始值。当调用函数Swap()时,为形参(即函数的参数)x和y分配存储空间,并将a和b的值复制过来,函数执行过程中,将x和y的值进行交换,当函数执行结束之后,x和y所占用的存储空间将被释放,这种传递的方式,并不会对实参a和b的值产生影响,此即为值传递。
引用传递:

当定义一个引用时,其实是为目标变量起一个别名,引用并不分配独立的内存空间,它与目标变量公用其内存空间。使用引用参数可以直接操作实参变量,从而能够实现通过修改形参的值而达到修改对应实参值得目的。

5、编写递归函数

1、什么是递归函数:简单说,就是函数自己调用自己。

基本思想是把规模大的、较难解决的问题变成规模较小的、易解决的同一问题。规模较小的问题又变成规模更小的问题,并且小到一定程度可以直接得出它的解,从而得到原来问题的解。 

long factorial(int n)
{
    if( n<=0 ) return 1;
    else return n*factorial(n-1);
}

2、递归函数的优点

代码简洁,清晰。

3、如何编写递归函数

(a):    解决问题时,可以把一个问题转化为一个新的问题,而这个新的问题的解决方法仍与原问题的解法相同,只是所处理的对象有所不同,这些被处理的对象之间是有规律的递增或递减;

比如在在阶乘函数中,n*factorial(n-1)就是反复重复的算法

(b):    必须要一个出口,结束递归函数的条件,比如  n*factorial(n-1)  n反复减1,直到n<=0时,函数结束,根据返回值在一步一步的返回。

#include <iostream>

using namespace std;

int fa(int n)
{
    int sum = 1;

    if(1 == n)
    {
        return 1;
    }

    sum =n * fa(n - 1);

    return sum;
}

int main()
{
    int num = 0;
    cin >> num;
    cout << fa(num) << endl;  
    return 0;
}

 

posted @ 2019-09-15 15:42  aakihi  阅读(187)  评论(0编辑  收藏  举报