Search code examples
c++pointersvoid

Passed by reference in c++ explanation


I am self studying c++ and I am stuck in the pointers. Particularly in different functions that call the pointers and change them. I know that for the majority of you here this is very simple but I need some explanation if someone can help me. I am using Xcode on macOS to run c++.

The code that I have is :


#include <iostream>

int a = 2, b = 17, c = 1;

void p(int a, int &c) {
    int b = a * c++;
    std::cout <<a <<" "<< b <<" "<< c << std::endl;
    if (4 * a > c) {
        p(b / 2, a);
        std::cout <<a <<" "<< b <<" "<< c << std::endl;
    }
}

int main() {

    p(c, a);
    std::cout <<a <<" "<< b <<" "<< c << std::endl;
    return 0;
}

with output :

1 2 3
1 1 2
0 0 2
2 1 2
2 2 3
3 17 1

In the beginning it calls p(a=1,c=2) where c is a pointer. And also the order of actions in c++ is that first it dereferences c and then it increments c by one. Therefore a = 1, b=3 , c = 3. Why it gives a = 1, b = 2, c = 3 ?


Solution

  • In the early days of the C language, the only calling convention was pass by value. That means that a function only receives a copy of its parameters, and if it changes a parameter, only the local copy is changed and the outer variable still has its initial value when the function returns. So to allow a function to change some variables, we passed pointers to those variables, which had to be dereferenced inside the function. Example code:

    void p(int a, int *c) {
        int b = a * (*c)++;  // outer c variable is increased
        std::cout <<a <<" "<< b <<" "<< *c << std::endl; // this is not C language ;-)
        ...
    }
    ...
    p(c, &a);    // explicitely pass a pointer to a
    

    Here we explicitely pass the address of the outer variable (with &c) and still explicitely derefence the pointer inside the function (*c).

    While being explicit can be fine, it implies cluttering the code with tons of & and * which is not very beginners friendly...

    Then C++ brought references. When you pass a variable by reference, the function has no longer a copy of the outer variable but directly uses it. Previous code can become:

    void p(int a, int &c) {
        int b = a * c++;  // outer c variable is increased thanks to the reference
        std::cout <<a <<" "<< b <<" "<< c << std::endl;
        ...
    }
    ...
    p(c, a);    // implicitely pass a reference to a