美文网首页
参数传递(一)

参数传递(一)

作者: Troll__Zhao | 来源:发表于2016-01-24 11:55 被阅读0次

    函数的形参一共分为两种:

    1. 当形参类型是引用类型的时候,我们说它对应的实参被引用传递或者说函数被传引用调用。
    2. 当形参类型是非引用类型的时候,我们说它对应的实参被传值传递或者是或函数被传值调用。

    传值参数

    当初始化一个非引用类型的变量的时候,初始值被拷贝给变量。这时候对变量进行的操作不会影响初始值:

    int n = 0;
    int i = n;      //i是n的副本
    i = 42;        //i的值改变,n的值不变
    

    传值参数的机理完全是一样的,函数对形参做的所有的操作都不会影响实参,比如:

    int fact(int val)
    {
        int ret = -1;
        while(val > 1)
            ret *= val--;
        return ret;
    }
    

    在上述代码中,尽管fact函数改变了val的值,但是这个改动并不会改变传入fact的实参。

    指针形参

    指针的行为和其他非引用类型一样。但是我们要知道,指针的实质是指向某个变量的地址,尽管我们对指针的形参的修改不会影响到实参,但是我们可以通过指针修改它所指向的对象的值:

    int n = 0, i = 42;
    int *p = &n, *q = &i;            //p指向n,q指向i
    *p = 42;                             //n的值改变,但是p不变
    p = q;                                 //p是q的副本,p指向i,但是i和n的值都不变
    

    指针形参也是类似:

    void reset(int *ip)
    {
        *ip = 0;                    //改变ip所指向的对象的值
        ip = 0;                     //改变了局部ip的拷贝,实参没有被改变
    }
    

    在上述代码当中,实参所指的对象变为0,但是实参本身并没有改变。

    传引用参数

    就像我们知道的那样,对于引用的操作实际上是作用在引用所绑定的对象上,下面就让我们看一下代码:

    void reset(int &i)
    {
        i = 0;              //改变了i所引对象的值
    }
    

    当我们调用上述版本的reset()函数的时候,i绑定我们传给函数的int对象,此时改变i的值就是改变i所引对象的值。

    使用引用避免拷贝

    当我们拷贝大的类型对象或者容器对象的时候比较低效,甚至有的类型根本不支持拷贝操作,例如IO类型,这时候我们只能用引用形参来访问该类型对象。
    比如,我们准备编写一个函数接受两个string类型的时候,想比较他们的长度,这时候我们拷贝的话效率过低,可以考虑传引用,这时候我们知道我们并不需要修改原实参,所以我们可以使用对常量的引用:

    bool isShorter(const string &s1, const string &s2)
    {
        return s1.size() < s2.size();
    }
    
    使用引用形参返回额外的信息

    我们知道,一个函数只能返回一个值,然而有时候函数需要同时返回多个值,引用形参可以巧妙的解决这个问题。
    例如,我们需要返回string对象中某个指定字符第一次出现的位置,同时也想要返回字符出现的总次数:

    string::size_type find_char(const string &s, char c, string::size_type &occurs)
    {
        auto ret = s.size();
        ocurrs = 0;
        for(decltype(ret) i = 0; i != s.size(); ++i)
        {
            if(s[i] == c)
            {
                if(ret == s.size())
                   ret = i;
               ++ocurrs
            }
        }
        return ret;
    }
    

    上述代码return了字符出现的位置,但是我们的形参有一个引用类型的:occurs,他可以直接让我们知道字符出现字数。

    相关文章

      网友评论

          本文标题:参数传递(一)

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