一、Python函数传参
在python中,函数传参实际上传入的是变量的别名,由于python内在的变量机制(名称和变量值相互独立),只要传入的变量不可变(tuple中的元素也要是不可变的才行),那么函数体内是无法直接修改传入的变量的。
假如我们把v=1传入函数体f(v1),实际就是新增了v1变量名,它和v同时指向1这个对象,如果我们在函数内部试图修改v1,由于整形是不可变的,实际上会创建一个新的对象,将v1指向新的对象,如果v指向的是可变对象,则内部对于其的修改会体现在外部上,这也是推荐tuple的原因之一。
另外,在python的局部作用域中,能够修改的对象必须是声明了的局部作用变量或者显示使用global声明的全局变量(其实使用nonlocal声明的自由变量也行),只要不修改值,单纯的读取的话,直接就可以读取全局变量,效果如下,尝试修改a时会报错,如果声明一下就可以避免:
二、C++中的函数传参
相比python,C++要灵活的太多,其参数传入有三种:
- 传入副本,最为广泛使用的方式,将参数值复制一份传入函数,函数的操作不影响原值
- 传入指针,实参使用地址,形参使用指针,可以在函数内部直接修改外部变量
- 传入引用,实参就是变量本身,形参需要加上&,此时不会拷贝出副本,而是将原数据直接传入,修改会直接体现在外部
下面程序是传入副本与传入指针的对比:
#include <iostream> using namespace std; void myswap_pass_by_reference(int a, int b) { int t = a; a = b; b = t; } void myswap_pass_by_pointer_value(int* a, int* b) { cout << *a << " " << *b << endl; int t = *a; *a = *b; *b = t; cout << *a << " " << *b << endl; } int main() { int a = 1, b = 2; cout << "originally" << endl; cout << "a=" << a << ", b=" << b << endl; myswap_pass_by_reference(a, b); cout << "after myswap_pass_by_reference" << endl; cout << "a=" << a << ", b=" << b << endl; myswap_pass_by_pointer_value(&a, &b); cout << "after myswap_pass_by_pointer_value" << endl; cout << "a=" << a << ", b=" << b << endl; return 0; }
下面程序是传入引用和传入指针的对比:
#include <iostream> using namespace std; void myswap_pass_by_reference(int& a, int& b) { int t = a; a = b; b = t; } void myswap_pass_by_pointer_value(int* a, int* b) { cout << *a << " " << *b << endl; int t = *a; *a = *b; *b = t; cout << *a << " " << *b << endl; } int main() { int a = 1, b = 2; cout << "originally" << endl; cout << "a=" << a << ", b=" << b << endl; myswap_pass_by_reference(a, b); cout << "after myswap_pass_by_reference" << endl; cout << "a=" << a << ", b=" << b << endl; myswap_pass_by_pointer_value(&a, &b); cout << "after myswap_pass_by_pointer_value" << endl; cout << "a=" << a << ", b=" << b << endl; return 0; }
可以看到,在调用了引用方式函数后,两个变量的值交换了次序。