07.函数

作者: Jameslong | 来源:发表于2017-04-21 10:50 被阅读0次

    这一节我们介绍函数,我们这里的函数和数学上的函数的意思一样么?答案是否定的。 有的编程语言比如Java就把函数成为方法,所以我们这里所要讨论的 函数实际上就是一个解决一般问题的过程,这个可以借助黑盒模型进行理解,现在函数就是一个黑盒,当我们向里面传入数据的时候,黑盒处理之后给出我们结果。

    黑盒模型

    是不是很抽象?用鼠标只能画成酱紫了(偷笑)。
    对应于黑盒模型,我们的函数可以传入0个或多个参数,然后返回一个结果,注意函数的出口只有一个那就是return语句,尽管在函数体中可能有多处出现return,但是我们要知道,函数最终返回到调用它的地方,所以出口只有一个。
    函数的标准写法是什么呢?
    我们有两种方式表示函数

    1.先声明后实现

    这里提一下main()函数,顾名思义,main()函数是程序的主函数,也就是说,我们的程序,从main()函数开始执行,所以也称为入口函数。
    函数的标准写法:
    返回类型 函数名(参类型 [参数名],参类型 [参数名],...);//[表示可有可无]
    int hello(int n);或者int hello(int);
    我们可以在main函数中调用函数A,但是函数A必须在main函数之前声明,不然main函数就认为不存在函数A,因为程序的编译过程是从上而下的。
    我们来看一段代码(Let's look at the wrong code...)

    #include<iostream>
    #include<string>
    using namespace std;
    
    int hello(int n);
    int main(){
        hello(5);
        return 0;
    }
    
    Paste_Image.png

    执行的时候报错,错误提示是说在main函数中引用了无法解析的符号,这是为什么呢?因为,尽管你尽管声明了hello函数,告诉main函数有个叫hello的函数存在,但是,这个函数真的存在么?当main函数按照名字去寻找的时候,发现不认识这个函数,也就是说这个函数没有定义。就像我们使用变量一样,你声明了一个变量,不给它赋值是不能直接拿来用的。

    int n;
    n = n+1;//这是不合法的,因为我们还没有给变量n赋初值
    

    为了能使main函数成功调用hello函数我们要给hello函数一个定义
    比如我们这样定义

    int hello(int n){
      for(int i =0;i<n;i++){
        cout<<"hello world"<<endl;
      }
    return 0;
    }
    

    我们定义了hello函数,就是输出n遍"hello world" ,当然可以有不同的定义,这也就是黑盒模型的本质,盒子里面可以是任何东西。
    把这个定义加入到刚刚的例子中试一下

    #include<iostream>
    #include<string>
    using namespace std;
    
    int hello(int n);
    
    int main(){
        hello(5);
        return 0;
    }
    int hello(int n){
        for (int i = 0; i < n; i++){
            cout << "hello world" << endl;
        }
        return 0;
    }
    
    Paste_Image.png

    great!
    这样我们的main函数就成功调用了hello函数,并且输入的数据是5,得到的结果是 屏幕上输出5行"hello world" 是不是很简单呀,快编写你的第一个函数吧(当然不包括main函数啦,嘿嘿,因为每个程序都要有main函数)

    2.同时声明、实现

    简单的思考一下,为了能够让main函数成功调用我们的函数A,我们要把函数的声明放在main之前,所以实现部分也要在main之前。
    返回类型 函数名称(参数类型 参数名称,参数类型 参数名称...){
    函数体
    }

    #include<iostream>
    using namespace std;
    
    int A(int n){
        int result=1;
        while (n)
            result *= n--;
        return result;
    }
    
    int main(){
        cout << A(5) << endl;
        return 0;
    }
    
    
    Paste_Image.png

    这里函数的声明和实现放在了一起,但是必须要在调用它的函数之前。这个函数A的功能是计算n的阶乘。
    以上实例都是main函数调用外部函数,那么函数之间能够互相调用呢?答案是肯定的。

    3.函数之间的调用

    这里只要记住一条,就是无论调用哪个函数,所被调用函数必须在调用者函数之前声明。

    int A(){
    do something ...
    }
    int B(){
    A();
    }
    

    这里的函数B就调用了函数A
    有的人要问,那函数A能不能调用函数B呢,答案也是肯定的。但是在A之前要先声明B看下面的例子

    #include<iostream>
    using namespace std;
    void B();
    void A(){
        cout << "A" << endl;
        B();
    }
    void B(){
        cout << "B" << endl;
        A();
    }
    
    
    int main(){
        A();
        return 0;
    }
    
    

    这里我们main函数调用了A,A又调用了B,B又调用了A,A又调用了B,...,没错,这将会一直调用下去,也就构成了死循环。

    Paste_Image.png

    因为函数一直在调用,所以程序没法终止,截图为部分。那么我们有必要两个函数之间互相调用么,答案也是肯定的,因为我们外加一些条件就能够很好的利用他们了,看下例

    #include<iostream>
    using namespace std;
    static int n = 10;
    void B();
    void A(){
        if (n < 0)
            return;
        n--;
        cout << "A" << endl;
        B();
    }
    void B(){
        cout << "B" << endl;
        A();
    }
    
    
    int main(){
        A();
        return 0;
    }
    
    Paste_Image.png

    既然相互调用会构成死循环,我们就在函数里加入返回条件,若满足条件则直接返回,不在调用。这样就能达到我们的目的了。

    4.返回值类型

    既然函数都要有返回类型,那么返回类型有哪些呢?
    void
    int
    bool
    char
    string
    float
    ...
    没错只要能作为数据类型的都可以作为函数的返回类型,
    void表示返回为空,就是可以不返回,或者直接return;
    为什么要设置返回类型呢? 因为函数的输出结果大都会有类型,为了能够在调用处正确的给变量赋值,所以要写明函数的返回值类型

    5.形式参数(形参)

    什么是形式参数呢?形参就是传入到我们的黑盒(函数)的参数,在函数声明和定义的时候使用的,形参没有具体的数值,只有数据类型,当我们调用这个函数的时候,我们用实参传入,从而经过函数得到结果,实参与形参对应,实参表示参数不仅有数据类型,而且有具体的数值。

    #include<iostream>
    using namespace std;
    
    int A(int n){
        return n*2;
    
    }
    
    int main(){
        A(5);
        return 0;
    }
    
    
    Paste_Image.png

    这个图很好的反映了形参和实参的区别。

    形参出现在函数定义中,在整个函数体都可用,离开函数不能使用
    实参出现在主调函数中,进入被调函数后也不能使用
    函数调用时,主调函数把实参的值传递给被调函数的形参,从而完成从主调函数向被调函数的数据传送。

    函数的基本问题就讲到这里,以后会经常用到各种函数。

    相关文章

      网友评论

        本文标题:07.函数

        本文链接:https://www.haomeiwen.com/subject/zjfrzttx.html