-1

I'm having a small issue in trying to figure out why a zero is printed out at the end of my while loop.

#include <iostream>
using namespace std;

int x;

int CountDown(int x);
int CountUp(int x);

int main()
{


    int toCountUp = CountUp(x);

    cout << x << endl;



}


int CountUp(int x)
{
    x = 0;
    while(x <= 10)
    {
        cout << x << endl;
        x++;
    }
}

My best response would be that it is in the condition of the while loop. Or a return status from the function/main being fulfilled, but I don't have a return on there, and I know a function doesn't require a return statement but in this while loop I want there to be a integer returned, do I need to make the function void so there will be no return? But what about the parameter x that I need for the while loop?

code output:

0
1
2
3
4
5
6
7
8
9
10
0   < ---- this is the number I do not want.  

Thinking about it, it has to be a value returned at the end of the function, any ideas?

Thomas
  • 2,622
  • 1
  • 9
  • 16
  • That's the cout in the main function, it prints the global variable x. – Ruocco Feb 21 '18 at 01:27
  • X isn't given a value until the function is called, where exactly is the cout getting the 0 from? The cout prints out what that function does, right? The function doesn't call for a 0 to be printed out at the end. – Thomas Feb 21 '18 at 01:30
  • 4
    Global integers are initialized with zero by default. The zero at the end is printed out because you print a zero out at the end in main, which is what the global x is set to. – Arnav Borborah Feb 21 '18 at 01:31
  • 5
    *"I know a function doesn't require a return statement"* - With the exception of `main`, which is special, if the function has a non-void return type, it needs a return statement unless it is intended to terminate abnormally (for example, through an exception). Otherwise, you have undefined behavior. – Benjamin Lindley Feb 21 '18 at 01:33
  • 1
    Handy reading, if not a duplicate: [What's the difference between passing by reference vs. passing by value?](https://stackoverflow.com/questions/373419/whats-the-difference-between-passing-by-reference-vs-passing-by-value) – user4581301 Feb 21 '18 at 01:35
  • 3
    The function `CountUp` does not work on the global variable `x`, but on the parameter x, which is a *copy* of the global variable x (you pass it to the function by value, not by reference), so `CountUp` does not modify the value of `x`, which remains, as @ArnavBorborah explained, at zero. – Ruocco Feb 21 '18 at 01:36
  • 1
    More handy reading: [Shadowing variables](https://stackoverflow.com/questions/19621785/shadowing-variables) – user4581301 Feb 21 '18 at 01:37
  • 1
    `Returning 0` you have no return keyword in your code, please read compiler warnings. And return is not a function, so don't call it like `return(0)` – phuclv Feb 21 '18 at 01:48

4 Answers4

2

This outputs the values 0 through 10:

int toCountUp = CountUp(x);

Then, this outputs 0:

cout << x << endl;

The method does not change the value that is passed to it, it uses its own local copy of that variable.

Dave
  • 3,273
  • 1
  • 17
  • 15
0

At last 0 is printed in main() function because x is declared global.

If you want latest x after loop got over to be printed in main() then you should reference variable and don't declare it globally.

int CountUp(int &); /* function prototype*/

Since passed variable(actual argument) and reference variable having the same memory So modification will affects in calling function.

int CountUp(int &x) { /* catch with reference variable so that modification affects in calling function also */
    x = 0;
    while(x <= 10)
    {
        cout << x << endl;
        x++;
    }
}
Achal
  • 11,821
  • 2
  • 15
  • 37
0

—It's mainly because you are printing cout << x << endl; twice. Once in the int CountUp(int x) function itself, but again in the main function.

—It could've printed any given value of x at this point, but since you're setting x=0 outside of the While{} loop in the int CountUp(int x) function, it's printing 0 at the end after the function call is executed.

*int CountUp(int x)
{
    x = 0;
    while(x <= 10)
    {
        cout << x << endl;
        x++;
    }
}*

—Is there a reason why you are setting x=0 within the function? since you're passing x as a parameter in the function call, and adding 1 to it in the While{} loop until it's x<= 10? Asking because you're not returning x back to the main() function.

—In case you wanted to use the end value of x to countdown using CountDown(x), you may like to reset x=0 in the main() function after calling the block—

*int CountUp(int x)
{
    x = 0;
    while(x <= 10)
    {
        cout << x << endl;
        x++;
    }
}*
0

First read Shadowing variables and What's the difference between passing by reference vs. passing by value?

The int x parameter of CountUp shadows the global variable int x so inside CountUp, the only x is the parameter.

int CountUp(int x)

int x defines x as passed by value, so it is a copy of the x used to call CountUp in main. This different x is counted up to 10 and then discarded.

the global int x has static storage duration and is default initialized to zero for you. Do not try this trick with a variable with Automatic duration because unless it has a constructor that does something useful, the contents are uninitialized and their value is undefined.

Sideshow issue:

A function that has a non-void return type MUST return a value on ALL paths. If it does not, you have Undefined Behaviour and the compiler can generate hopelessly invalid code that can get you even if the bad path is not taken. Don't smurf with Undefined Behaviour, as it might crash the program or do something hilariously wrong, but it might also look like it works until it suddenly doesn't at a really bad time.

Solutions:

void CountUp(int & x)
{
    x = 0;
    while(x <= 10)
    {
        cout << x << endl;
        x++;
    }
}

Passes x by reference allowing global x and the local x to be one and the same and returns nothing. Usage would be

 CountUp(x);

Not so useful in the asker's case because it doesn't leave a toCountUp.

int CountUp(int x)
{
    x = 0;
    while(x <= 10)
    {
        cout << x << endl;
        x++;
    }
    return x;
}

Makes a copy if the provided x, operates on the copy, and then returns x. Usage would be

 int toCountUp = CountUp(x);

And will set toCountUp to 10 higher than the global x.

user4581301
  • 33,082
  • 7
  • 33
  • 54