What does int & mean

后端 未结 6 774
隐瞒了意图╮
隐瞒了意图╮ 2020-12-12 15:39

A C++ question,

I know

int* foo(void)

foo will return a pointer to int type

how about

int &foo(void)
         


        
6条回答
  •  甜味超标
    2020-12-12 16:23

    Be careful here... you're walking the C/C++ line. There's a quite clear distinction but it doesn't always appear that way:

    C++: this often means a reference. For example, consider:

    void func(int &x)
    {
       x = 4;
    }
    
    void callfunc()
    {
        int x = 7;
        func(x);
    }
    

    As such, C++ can pass by value or pass by reference.

    C however has no such pass by reference functionality. & means "addressof" and is a way to formulate a pointer from a variable. However, consider this:

    void func(int* x)
    {
       *x = 4;
    }
    
    void callfunc()
    {
        int x = 7;
        func(&x);
    }
    

    Deceptively similar, yet fundamentally different. What you are doing in C is passing a copy of the pointer. Now these things still point to the same area of memory, so the effect is like a pass by reference in terms of the pointed-to memory, but it is not a reference being passed in. It is a reference to a point in memory.

    Try this (Compile as C):

    #include 
    
    void addptr(int* x)
    {
        printf("Add-ptr scope 1:\n");
        printf("Addr: %p\n", x);
        printf("Pointed-to-memory: %d\n", *x);
        *x = *x + 7;
        x++;
        printf("Add-ptr scope 2:\n");
        printf("Addr: %p\n", x);
        printf("Pointed-to-memory: %d\n", *x);
    }
    
    int main(int argc, char** argv)
    {
        int a = 7;
        int *y = &a;
        printf("Main-Scope 2:\n");
        printf("Addr: %p\n", y);
        printf("Pointed-to-memory: %d\n", *y);
        addptr(y);
        printf("Main-Scope 2:\n");
        printf("Addr: %p\n", y);
        printf("Pointed-to-memory: %d\n", *y);
        return 0;
    
    }
    

    If C had pass by reference, the incoming pointer address, when changed by addptr should be reflected in main, but it isn't. Pointers are still values.

    So, C does not have any pass by reference mechanism. In C++, this exists, and that is what & means in function arguments etc.

    Edit: You might be wondering why I can't do this demonstration in C++ easily. It's because I can't change the address of the reference. At all. From this quite good guide to references:

    How can you reseat a reference to make it refer to a different object?

    No way.

    You can't separate the reference from the referent.

    Unlike a pointer, once a reference is bound to an object, it can not be "reseated" to another object. The reference itself isn't an object (it has no identity; taking the address of a reference gives you the address of the referent; remember: the reference is its referent).

    In that sense, a reference is similar to a const pointer such as int* const p (as opposed to a pointer to const such as int const* p). But please don't confuse references with pointers; they're very different from the programmer's standpoint.

    By request, on returning references:

    #include 
    
    using namespace std;
    
    int& function(int f)
    {
       f=f+3;
       return f;
    }
    
    int main(int argc, char** argv)
    {
        int x = 7;
        int y;
        y = function(x);
        cout << "Input: " << x << endl;
        cout << "Output:" << y << endl;
        return 0;
    }
    

    Any good compiler ought to give you this warning message in some form:

    exp.cpp:7:11: warning: reference to stack memory associated with local variable 'f' returned

    What does this mean? Well, we know function arguments are pushed onto the stack (note: not actually on x64, they go into registers then the stack, but they are on the stack literally on x86) and what this warning is saying is that creating a reference to such an object is not a good idea, because it's not guaranteed to be left in place. The fact it is is just luck.

    So what gives? Try this modified version:

    #include 
    
    using namespace std;
    
    int& function(int& f)
    {
        f=f+3;
        return f;
    }
    
    int main(int argc, char** argv)
    {
        int x = 7;
        int y;
        y = function(x);
        cout << "Input: " << x << endl;
        cout << "Output:" << y << endl;
        return 0;
    }
    

    Run this, and you'll see both values get updated. What? Well they both refer to the same thing and that thing is being edited.

提交回复
热议问题