C++之值传递和引用传递

值传递和引用传递


值传递

当实参的值被拷贝给形参时,实参和形参是两个独立的变量,我们说实参被值传递或者函数被传值调用。

- 普通形参
形参与实参独立,对形参的改变不会影响实参。

 int i = 0;
 void change(int z)
 {
     z = 43;  //i的值仍为0
 } 
change(i);

上述代码执行完毕后i的值仍是0;

- 指针形参
当执行指针拷贝操作时,拷贝的是指针的值指针的值,拷贝之后两个指针是不同的指针。通过指针可以间接修改指针所指向的对象。

int i = 0;
void change(int  *p)
{
    *p = 43;    //i的值为43
    p = 0;      //只改变指针p的局部拷贝,实参未改变
} 

引用传递

将形参绑定到实参,对引用的操作实际上是作用在引用所引的对象上。使用引用传递的优势:

  • 使用引用避免拷贝——如果函数无须修改引用形参的值,最好将其声明为常量引用;
bool isShorter(const string &s1, const string &s2)
{
    return s1.size() < s2.size();
}
  • 使用引用形参可以返回额外的信息,因修改形参对传入的实参有效。
int i = 0;
void change(int &p)
{
    p = 43;    //i的值为43
} 

const 形参和实参

顶层const & 底层const

顶层const:指针本身是常量,指针所指的对象不是常量。
底层const:指针所指向的对象是常量。

 int i = 0;
 const int ci = 4;  //顶层const,不允许改变ci的值
 int *const p1 = &i; //顶层const,不能改变p1值
 const int *p2 = &ci; //底层const, 允许修改p2的值

指针或引用形参与const

    void reset(int *i)
    {
        *i = 0; //改变i指向的值
    }
    void reset(int &k)
    {
        k = 0; //改变k指向的值
    }

形参初始化方式与变量初始化方式一样。

变量初始化方式

    int i= 0const int* cp = &i; //底层const,cp不能改变i的值
    const int &r = i;  //底层const, 但是r不能改变i
    const int &r2 = 42//字面量初始化一个常量引用

    int *p = cp;  //错误,p的类型不是常量指针
    int &r3 = r; //错误,r3得类型和r的类型不匹配
    int &r4 = 42; //错误,不能用字面量初始化一个非常量引用 

形参初始化方式

扫描二维码关注公众号,回复: 188581 查看本文章
    int i= 0;
    const int ci = i;
    string::size_type ctr = 0;
    reset(&i);    //调用形参类型是int*的reset函数
    reset(&ci);   //错误,不能用指向const int对象的指针初始化int*
    reset(i);   //调用形参类型是int&的reset函数 
    reset(4);    //不能把字面量绑定至普通类型上
    reset(ctr);    //类型不匹配

总结:当函数不对传入的形参做改变时,应将该形参设置为常量引用。将函数不会改变的形参定义为普通引用容易让调用者误会,即该参数可以被修改。且我们不能把const对象、字面量值传递给普通引用形参。例:reset(4); //不能把字面量绑定至普通类型上

猜你喜欢

转载自blog.csdn.net/ty13438189519/article/details/80059715
今日推荐