函数的参数传递方式

  在本学期(大三春)“编译系统”上,辛(明影)老师问了这样一个问题:

    源程序如下,问函数Produce参数按照“传值调用”、“传地址调用”的最终输出:

Produce(x, y, z):
    y = y + 1;
    z = z + x;

Main():
    int a = 2, b = 3;
    Produce(a+b, a, a);
    print(a);

  直观来说,“传值调用”肯定是对实参没有任何影响,其结果自然依旧是2。

  对于传地址调用来说,我第一想法就是相当于直接把实参传递给函数,也就是将函数形参定义为引用,那么... 肯定会报错啊!

  通过用可爱的std::C++11跑了一下,果然如果将第一个形参定义为int &类型,将会报错。

  报错原因很简单:调用过程将一个右值绑定到了一个左值引用上了... 

  自然,就改成右值引用类型(int &&)来验证试验结果:

#include <iostream>

// 传值调用
void produce_by_val(int x, int y, int z) {
    y = y + 1;
    z = z + x;
}

// 传地址调用
void produce_by_ref(int &&x, int &y, int &z) {
    y = y + 1;
    z = z + x;
}

int main(int argc, char *argv[]) {
    int a = 2, b = 3;
    produce_by_val(a+b, a, a);
    std::cout << a << std::endl;
    a = 2, b = 3;
    produce_by_ref(a+b, a, a);
    std::cout << a << std::endl;
    return 0;
}

  实验结果很满意:

Output:
2
8

  传值调用就不解释了,对于传地址调用来说,函数调用过程如下:

  在main函数中,调用produce_by_ref时,先计算a+b的值,将这个值保存到一个临时地址中,然后将这个临时地址传递给produce_by_ref形参,然后就很好理解了。

  a先自增1,此时a=3。然后a又加上那个临时地址存储的值(即2+3=5),此时的a值为8。写回到a的地址中,自然得到a=8的结果。

  还有一种函数传递方式,得到的值为9,至于哪种传递方式,想起来再补上......(尴尬,逃...)

 

  @编辑于2019.3.6

posted @ 2019-03-06 17:01  Modnar  阅读(311)  评论(0编辑  收藏  举报