1

So I'm beginning to learn C++ and came upon this example--

#include <iostream>

void doIt(int x)
{
    x = 3;
    int y = 4;
    std::cout << "doIt: x = " << x << " y = " << y << std::endl;
}

int main()
{
    int x = 1;
    int y = 2;
    std::cout << "main: x = " << x << " y = " << y << std::endl;
    doIt(x);
    std::cout << "main: x = " << x << " y = " << y << std::endl;
    return 0;
}

--and for the sequence where doIt() is called, doit: x = 3 y = 4 is printed. Maybe there is some unknown thing I could search to better understand what happened, but essentially what I'm wondering is whether x was passed to the function as a variable or as its value (1). If it were passed as 1, wouldn't there be an error? Does this mean that the function would require an integer variable rather than a standalone integer? This program was intended to show how these variables are local, but I'm not sure how it all fits together.

  • Difference between pass by value and pass by reference... – Jarod42 Dec 21 '15 at 19:56
  • 1
    I think you might need to read a good [C++ book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) to understand how calling functions work. – NathanOliver Dec 21 '15 at 19:56

4 Answers4

0

Variables are not passed to functions - values are. (If we say a "variable was passed to a function", it's just short for saying the value of the variable was passed to the function)

When doIt is called, x and y in doIt are brand new variables, unrelated to the ones in main. The first parameter's value (which is the value of x in main, which is 1) is stored in x. Then, 3 is stored in x (by the line x = 3;). Then, 4 is stored in y. Then you print x and y, which contain the values 3 and 4.

Once doIt returns, main's variables haven't been changed, because they're different variables (that coincidentally have the same name). So main prints 1 and 2 again.

user253751
  • 57,427
  • 7
  • 48
  • 90
  • If the values are what's being passed, why is there no error from 1(x) = 3? – A.J. Hulgus Dec 21 '15 at 20:05
  • @A.J.Hulgus Because `x` is a variable? Why's there no error from `int i = 7; i = 6;`? – user253751 Dec 21 '15 at 20:07
  • `x` is a variable (both `x`es), but neither of the variables themselves are passed, only the value. – user253751 Dec 21 '15 at 20:08
  • Yeah I guess that was kind of a convoluted follow-up question. I was thinking that the value being passed would replace any instance of the placeholder for parameters, which would have resulted in 1 = 3, but now it seems like a new variable is actually created which is set equal to the argument. Maybe this is right? Either way thank you! – A.J. Hulgus Dec 21 '15 at 20:18
  • @A.J.Hulgus Yes. `x` in `doIt` is a new variable which is set equal to the argument. – user253751 Dec 21 '15 at 20:21
0

x is passed by value but a new x is created in the method. The new x will have the value passed into the method. The new x is limited in scope to the method: a local variable.

You can assign the local x it a new value, as your code does. It will not affect the variable in the calling method.

nicomp
  • 4,344
  • 4
  • 27
  • 60
  • Does this mean that passing x is like putting doIt((int x created for function) = (x or whatever value is being passed))? – A.J. Hulgus Dec 21 '15 at 20:07
  • yes. It all happens automagically for you. The local variable with the same name is created and destroyed for you. – nicomp Dec 21 '15 at 20:10
0

When a function takes an plain argument (such as int x) the compiler will pass the VALUE to the called function (aka "callee"). Inside the callee, that value is stored in a local variable [1], so when you update it by saying x = 3, the COPY inside the function is updated, not the original value in the caller.

This is a good thing, because it means you can pass a value to a function wihtout having to KNOW if the function changes it or not.

If you want to modify the value of an input variable, it needs to be a reference, void doIt(int &x) - in which case the compiler will pass the actual variable by reference, such that you can modify it [technically, this means passing the address of the variable, rather than it's content, and then relevant code in the callee to handle the difference].

[1] Yes, technically, that copy is most often done at the caller code.

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
  • Thanks! Slightly unrelated, but I couldn't help but notice how amazingly fast these answers come. Do people just go to this website and answer questions for fun? – A.J. Hulgus Dec 21 '15 at 20:20
  • Yes, something like that. Why else do you think people answer questions? Nobody here is being paid specifically to answer questions (or if they are, I'd like to know how you get paid! ;) ) – Mats Petersson Dec 21 '15 at 20:22
  • I also hang around here because I get to learn from other people's answers. – ForeverStudent Dec 21 '15 at 20:35
0

When you pass an integer to your function doIt(int x), the int you are passing will be copied. therefore anything you do to x inside the body of doIt() will be exclusive to the copy that lives in doIt()

notice that the name of the variable could be the same, or could be different. it makes no difference. if you are passing by VALUE, the variable content will ALWAYS be copied.

#include <iostream>

void doIt(int x) //x here is completely different value than in main
                 //even though they have the same name
{
    x = 3; //this variable has its own scope
    int y = 4;
    std::cout << "doIt: x = " << x << " y = " << y << std::endl;
} //at the end of this function x is destroyed

int main()
{
    int x = 1;
    int y = 2;
    std::cout << "main: x = " << x << " y = " << y << std::endl;

    doIt(x); //the content of variable x will be passed by value to doIt()

    std::cout << "main: x = " << x << " y = " << y << std::endl;
    return 0;
}

There is another way to pass parameters in C++ which is pass by reference semantics. it looks like this:

void doIt(int &z) //z is passed by reference, changing it will stick
//z is the SAME variable that was passed in, even if the name is different
{
    z = 3; //this will change the value that was passed in
    int y = 4;
    std::cout << "doIt: z = " << x << " y = " << y << std::endl;

} //z is not destroyed here, because it wasnt created in this scope

int main()
{
    int x = 1;
    int y = 2;
    std::cout << "main: x = " << x << " y = " << y << std::endl; //x is 1
    doIt(x);
    std::cout << "main: x = " << x << " y = " << y << std::endl; //x is 3 now
    return 0;
}

Pass by reference will "secretly" send your variable by its memory address, so the int that your function receives will actually be the SAME one that was passed in. Note that I chose the variable name z because the name of the variable in different scopes doesn't actually matter.

ForeverStudent
  • 2,487
  • 1
  • 14
  • 33
  • What do you mean by that? I do learn much better when I ask follow-up questions, but yeah I guess I probably should have read all of the answers before asking additional questions. – A.J. Hulgus Dec 22 '15 at 01:48
  • No, followup questions are good :) I meant you should pick a best answer so the question is solved. It awards reputation for people who take the time to explain – ForeverStudent Dec 22 '15 at 02:10