C++7.2.1 参数传递--非引用形参

来源:互联网 发布:apache2 for windows 编辑:程序博客网 时间:2024/06/07 08:27

简介

  • 当我们调用一个函数时,第一件事就是创建形参的那两个变量,并将这两个变量初始化为调用函数时传递的实参值

  • 当我们使用普通的形参(非引用类形参)时,实参对形参的初始化就是直接执行复制操作,将实参的值复制给形参。在本节和后面讨论引用类型(7.2.2节)的形参时会讨论到这个问题,就是直接执行复制有时候会效率很低——(7.1节)

  • 每次调用函数时,都会重新创建该函数所有的形参,此时所传递的实参将会初始化对应的形参

    • 当用实参副本初始化形参时,函数并没有访问调用所传递的实参本身,因此不会修改实参的值。
  • 非引用形参表示对应实参的局部副本,对这类形参的修改仅仅改变了局部副本的值,一旦函数执行结束,这些局部变量的值也就没有了。

  • 函数的形参可以是指针,此时将复制实参指针,与其他非引用类型的形参一样,该类形参的任何改变也仅作用与局部副本,如果函数将新指针赋给形参,主调函数使用的实参指针的值没有改变;

  • 复制实参并不是在所有的情况下都适合,不适宜复制实参的情况如下,在如下的情况中,有效的解决办法是将形参定义为引用或指针类型:

    • 当需要在函数中修改实参的值时

    • 当需要以大型对象作为实参传递时,对实际应用而言,复制对象所付出的时间和存储空间代价往往过大

    • 当没有办法实现对象的复制时

    important

=========================================================================================================

一、非引用形参

1、非引用形参

  • 每次调用函数时,都会重新创建该函数所有的形参,此时所传递的实参将会初始化对应的形参

  • 当用实参副本初始化形参时,函数并没有访问调用所传递的实参本身,因此不会修改实参的值。

  • 非引用形参表示对应实参的局部副本,对这类形参的修改仅仅改变了局部副本的值,一旦函数执行结束,这些局部变量的值也就没有了。

  • 事实上被复制的指针只影响对指针的赋值,如果函数形参是非const类型的指针,则函数可以通过指针实现赋值,修改指针所指对象的值。

  • 如果需要保护指针所指向的值,则形参需定义为指向const对象的指针( const int * p)

int gcd(int v1,int v2){    while(v2){     int temp=v2;     v2=v1%v2;     v1=temp;}return v1;}//while 循环虽然修改了v1和v2的值,但这些变化仅限于局部参数,而对调用gcd 函数使用的实参没有任何影响。

2、指针形参

  • 函数的形参可以是指针,此时将复制实参指针,与其他非引用类型的形参一样,该类形参的任何改变也仅作用与局部副本,如果函数将新指针赋给形参,主调函数使用的实参指针的值没有改变;

  • 指针形参是指向const 类型还是非const类型,将影响函数调用所使用的实参。

  • 事实上被复制的指针只影响对指针的赋值,如果函数形参是非const类型的指针,则函数可以通过指针实现赋值,修改指针所指对象的值。

  • 如果需要保护指针所指向的值,则形参需定义为指向const对象的指针( const int * p)

void reset(int * p){*ip=0;//修改ip指针所指对象的值ip=0;//仅仅修改ip 局部副本的值}
//调用reset后,实参依然保持原来的值,但它所指对象的值将变成0int i=42;int *p=&i;cout<<"*i:"<<*p<<endl;//输出42reset(p);//修改指针所指对象的值cout<<"i:"<<*p<<endl;//输出 0
//将指针定义为指向const对象的指针,保护指针所指的对象void use_ptr(const int *p){}//指向const对象的指针可以用const和非const对象进行赋值,但是不能通过指针对其所指对象的值进行修改。//看《 C++primer 4.2 指针和const限定符(3)》

3、const 形参

  • 如果在函数使用非引用的非const形参,则既可以给该函数传递const实参,也可以传递非const的实参。(就像你可以给一个非const对象赋值一个const或非const的值)

  • 如果形参定义为非引用类的const类型,则在函数中,不能改变实参的局部副本,但是可以通过const和非const给形参赋值。(可以给一个const对象赋值一个const或非const的值)

const int i=3,j=6;int k=gcd(3,6);//实参是const非引用的,形参不是const非引用的void fcn(const int i);//形参定义为const类型,实参可以是

4、复制实参的局限性

  • 复制实参并不是在所有的情况下都适合,不适宜复制实参的情况如下,在如下的情况中,有效的解决办法是将形参定义为引用或指针类型:

    • 当需要在函数中修改实参的值时

    • 当需要以大型对象作为实参传递时,对实际应用而言,复制对象所付出的时间和存储空间代价往往过大

    • 当没有办法实现对象的复制时

0 0
原创粉丝点击