在本学期(大三春)“编译系统”上,辛(明影)老师问了这样一个问题:
源程序如下,问函数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