Pass-by-reference differences in C++ vs Python

南笙酒味 提交于 2021-01-01 09:18:24

问题


I have a little bit of C++ background. I am currently learning Python and am trying to understand how the function parameters are passed. I know this question is asked numerous times up here, but since I am not a Computer Science major, a lot of discussions threads are rather esoteric to me, plus, I've not seen a lot of comparisons on this topic between different languages, so I thought I'd give a new post a try.

The situation is this: My understanding is that Python only pass by reference (i.e. pass the value of the variable name, which I believe is the location address.) Under this impression, I went back to my old C++ textbook hoping to refresh my memory on how pass by reference works. But then I discovered that passing by reference in C++ seemed to work differently from passing by reference in Python. An example would be that variable reassignment affected the original variable in C++ but not in Python.

Below are codes and outputs of my experiments in C++ and in Python. The C++ code was from C++ Programming: From Problem Analysis to Program Design (6th Edition) by D.S. Malik; the Python code was my translation of the C++ code. Note that the C++ example contains both pass-by-value and pass-by-reference.

So, here come my questions: Is the definition of pass-by-reference language-specific? How does Python parameter passing work? Are there any incorrect logics in what I just said? Any clear and simple layman explanation would be greatly appreciated.

C++ code

//Example 6-13: Reference and value parameters

#include <iostream>

using namespace std;

void funOne(int a, int& b, char v);
void funTwo(int& x, int y, char& w);

int main()
{
    int num1, num2;
    char ch;
    num1 = 10; //Line 1
    num2 = 15; //Line 2
    ch = 'A'; //Line 3
    cout << "Line 4: Inside main: num1 = " << num1
        << ", num2 = " << num2 << ", and ch = "
        << ch << endl; //Line 4
    funOne(num1, num2, ch); //Line 5
    cout << "Line 6: After funOne: num1 = " << num1
        << ", num2 = " << num2 << ", and ch = "
        << ch << endl; //Line 6
    funTwo(num2, 25, ch); //Line 7
    cout << "Line 8: After funTwo: num1 = " << num1
        << ", num2 = " << num2 << ", and ch = "
        << ch << endl; //Line 8
    return 0;
}

void funOne(int a, int& b, char v)
{
    int one;
    one = a; //Line 9
    a++; //Line 10
    b = b * 2; //Line 11
    v = 'B'; //Line 12
    cout << "Line 13: Inside funOne: a = " << a
        << ", b = " << b << ", v = " << v
        << ", and one = " << one << endl; //Line 13
}

void funTwo(int& x, int y, char& w)
{
    x++; //Line 14
    y = y * 2; //Line 15
    w = 'G'; //Line 16
    cout << "Line 17: Inside funTwo: x = " << x
        << ", y = " << y << ", and w = " << w
        << endl; //Line 17
}

C++ output

Inside main: num1 = 10, num2 = 15, and ch = A
Inside funOne: a = 11, b = 30, v = B, and one = 10
After funOne: num1 = 10, num2 = 30, and ch = A
Inside funTwo: x = 31, y = 50, and w = G
After funTwo: num1 = 10, num2 = 31, and ch = G

Python code

def funOne (a, b, v):
    one = a
    a += 1
    b = b * 2
    v = 'B'
    print("Inside funOne: a", a, "b", b, "v", v, "one", one)

def funTwo (x, y, w):
    x += 1
    y = y * 2
    w = 'G'
    print("Inside funTwo: x", x, "y", y, "w", w)

num1 = 10
num2 = 15
ch = 'A'

print("Inside main: num1", num1, "num2", num2, "ch", ch)
funOne(num1, num2, ch)
print("After funOne: num1", num1, "num2", num2, "ch", ch)
funTwo(num2, 25, ch)
print("After funTwo: num1", num1, "num2", num2, "ch", ch)

Python output

Inside main: num1 10 num2 15 ch A
Inside funOne: a 11 b 30 v B one 10
After funOne: num1 10 num2 15 ch A
Inside funTwo: x 16 y 50 w G
After funTwo: num1 10 num2 15 ch A

Thanks.


回答1:


The closest thing to a Python reference in C++ is a smart pointer. In fact CPython uses reference counted pointers similar to std::shared_ptr.

This Python function:

def foo(an_int, a_string, list_of_int):

Is roughly equivalent to:

variant foo(shared_ptr<const int> an_int, shared_ptr<const string> a_string, shared_ptr<vector<shared_ptr<const int>>> list_of_int) {



回答2:


"Pass by reference" means that the function receives the address of the caller's variable, and when it assigns to the parameter it modifies the caller's variable.

In C++, this has to be specified explicitly in the function, by putting & before the parameter name in the function declaration. Otherwise, parameters are passed by value (although in the case of arrays, the array name decays to a pointer to its first element, so it's similar to pass by reference).

Python does not do this at all, it uses pass by value. But if the value is a structured object like a list or dictionary, the value is a reference to the object, not a copy of it. So if the function modifies the contents of the object, it affects the caller's variable as well. But it's not the same as pass by reference, because if the function simply assigns to the parameter variable it has no effect on the caller's variable.

And this does not happen at all for immutable values such as numbers and strings. There's no way to modify the contents of such values. All you can do is assign to the variable, and as stated above that has no effect on the caller's variable.




回答3:


Python arguments are passed by assignment. There is good explanation here-

How do I pass a variable by reference?



来源:https://stackoverflow.com/questions/41773606/pass-by-reference-differences-in-c-vs-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!