代码改变世界

第二次作业

2019-09-16 23:42  艾伦爱尔敏  阅读(163)  评论(0编辑  收藏  举报

1.为什么用函数

       一个较为复杂的系统往往需要划分为若干子系统,然后对这些子系统分别进行开发和调试。高级语言中的子程序就是用来实现这种模块划分的。c和c++语言中的子程序体现为函数。通常将相对独立的、经常使用的功能抽象为函数。函数编写好以后,可以被重复利用,可以提高开发效率、增强程序的可靠性,也便于分工合作和修改维护。

#include <iostream>
using namespace std;
int main()
{
    int a = 1, b = 2, c;
    c = a + b;
    cout << c << endl;
    return 0;
}
#include <iostream>
#include "pch.h"
using namespace std;
int add(int a, int b)
{
    int c;
    c = a + b;
    return c;
}
int main()
{
    int a = 1, b = 2, c;
    c = add(a, b);
    cout << c << endl;
    return 0;
}

如此可见运用函数,下次再次进行加法运算时,可再次运用此函数。

2.函数的重载

  运用函数的重载可以使一个函数的功能更加齐全。可以使一个只进行整型数字加法的函数同时进行浮点型的运算。

int add(int a, int b)
{
   int c;
  c = a+b;
  return c; 
}
float add(float a, float b )
{
  float c;
  c = a + b;
  return c;
}

例如上述两个函数,名字完全一样,但是返回值以及参数类型不同,函数体也略有差别,此为函数的重载。

3.值传递

首先讨论函数的传值,顾名思义函数的传值仅仅是把实参的值传递给了形参的值,这也就是说实参与形参之间互不影响,仅仅因为函数的需要其值相同而已。在这里我们把它形象地想象成数学中一个函数f(x),而现在我们要求f(a),当我们运算完成后,a的值还是它原来的那个数,而我们的f(x)函数仍然可以继续做f(b)、f(c)等一系列运算,这里就可以将这种特质类推到c++语言中的函数利用函数过后会将其形参值释放掉的模式,我认为函数的设计初衷也是如此。

以上内容间接说明了函数传值并不能改变实参的值,下面我们用一个最常见的例子来说明此特质:

复制代码
#include<iostream>
using namespace std;
void swap(int a, int b)
{
    int x;
    x = a;
    a = b;
    b = x;
    cout << a << " " << b << endl;
}
int main()
{
    int a = 1, b = 2;
    swap(a, b);
    cout << a << " " << b << endl;
    return 0;
}
复制代码

运行结果为:2 1

                      1 2

  由此可看出交换函数swap并没有改变主函数中a与b的值。

4.址传递

由以上的例子表明,函数并不能做到更改主函数的值,所以人们就想到了利用地址来间接更改地址中的值,也就是所谓的函数的传址。

  函数的传址就是主函数中的实参是一个地址变量,而相对应的被调用函数的形参也是一个地址变量(也就是指针变量)。这个变量中存着地址,可以在被调函数中对其所指向的地址中的数值进行更改,而如介绍传值时所说的调用结束后会释放形参,而传址的方式使得函数释放的不是指针指向的值而是指针本身。所以c++通过这种函数传递方式来完成对主函数中的值的改变。

  下面用例子更加直观地描述:

复制代码
#include<iostream>
using namespace std;
void swap(int *a, int *b)
{
    int x;
    x = *a;
    *a = *b;
    *b = x;
    cout << *a << " " << *b << endl;
}
int main()
{
    int *a, *b, c = 1, d = 2;
    a = &c;
    b = &d;
    swap(a, b);
    cout << *a << " " << *b << endl;
    return 0;
}
复制代码

 

注意:在c++中,如果想在函数中更改某个指针的值,参数是指针是做不到更改其值的,应使用指针的指针来进行更改。因为参数传递的本质仍然是传值。

5.递归函数

  解决递归问题的方法要找到递归方程和终止条件。下面看一个最典型的例子汉诺塔:

 1 #include<iostream>
 2 using namespace std;
 3 void move(char src, char dest)
 4 {
 5 cout << src <<"-->" <<dest << endl;
 6 }
 7 void hanoi(int n, char src, char medium, char dest)
 8 {
 9 if(n == 1)
10   move(src, dest);
11 else 
12 {
13   hanoi (n -1, src, dest, medium);
14   move(src, dest);
15   hanoi(n -1, medium, src, dest);
16 }
17 }
18 int main()
19 {
20   int m;
21 cout << "the steps to moving" << m << "diskes:" << endl;
22 cin >> m;
23 hanoi (m, 'A', 'B', 'C');
24 return 0;
25 }

 

 

例子中的递归方程就是13-15行,而终止条件就是当n=1时,所有诋毁问题都是如此,找到递归方程与终止条件。而难点就在于找到递归方程,找递归方程要抽象地解决问题,而有些问题就不能去从具体每个数据中找到规律从而得出递归方程。