2

I'm new and just learning C++ and came across this problem that I've spent maybe an hour trying to fix and researching answers on but I cant seem to figure out what I'm doing wrong. I'm using Visual Studios as my IDE, the most recent version.

#include "stdafx.h"
#include <iostream>
#include "constant.h"

//height of the tower
double towerHeight(double x)
{
    using namespace std;
        cout << "Enter a height for the tower" << '\n';
        cin >> x;

        return x;
}

//the number of seconds since the ball has been dropped to determine the distance
double secondsSinceDrop(double x)
{
    using namespace std;
        cout << "How long has it been since you dropped the ball (Seconds): ";
        cin >> x;

        return x;
}

//finds how far off the ground the ball is 
double currentBallHeight(double x, double y)
{
    return y * constant::gravity - x;
}

//prints how far off the ground the ball is
void printResult(double x, double y)
{
    using namespace std;
        if (currentBallHeight(x, y) < 0)
            cout << "At " << y << " the ball is on the ground." << '\n';
        else
            cout << "At " << y << " the ball is at: " << currentBallHeight(x, y) << '\n';
}

int main()
{
    double x = towerHeight(x);
    double y = secondsSinceDrop(x);

    printResult(x,y);

    return 0;
}

This is the Error Code - chapter 2 comprehensive quiz (part 2).cpp(46): error C4700: uninitialized local variable 'x' used

-Line (46) is - double x = towerHeight(x);

I've been getting this and I've changed my code around to get it down to just this one error but i cant figure out how to fix it. Its probably something simple and I'm dumb for overlooking it but any help would be greatly appreciated.

  • 1
    Read the error message. `x` is uninitialized. – MikeCAT Jul 14 '16 at 04:58
  • The implementations of `towerHeight` and `secondsSinceDrop` look weird because they don't use the passed values of the arguments (unless the readings fail) and use it as simple local variables. – MikeCAT Jul 14 '16 at 04:59

4 Answers4

1

Your first line of code in main() is double x = towerHeight(x);, what value of x are you sending to the function, when you have not initialized it. When you are using a variable without initializing the value of it is undefined.

You can pass the variable as a reference to your function and accept the values inside it.

//height of the tower
void towerHeight(double &x)
{
    using namespace std;
    cout << "Enter a height for the tower" << '\n';
    cin >> x;
}

//the number of seconds since the ball has been dropped to determine the distance
void secondsSinceDrop(double &y)
{
    using namespace std;
    cout << "How long has it been since you dropped the ball (Seconds): ";
    cin >> y;
}

int main()
{
    double x = 0.0, y = 0.0;
    towerHeight(x);
    secondsSinceDrop(y);
    printResult(x, y);
    return 0;
}
ani627
  • 5,578
  • 8
  • 39
  • 45
  • You may wish to mention how `double x = towerHeight(x);` is evaluated :) – sjsam Jul 14 '16 at 05:28
  • 1
    @sjsam: No I can't because order of evaluation is unspecified :) – ani627 Jul 14 '16 at 05:35
  • I actually meant how the expression itself is evaluated in the context of `sequence point` and `side effect`. But I don't think it will make much sense here coz the error is obvious which indeed means that current answer is fine. – sjsam Jul 14 '16 at 05:53
  • @sjsam my answer delves into helping to explain better how the code works without getting too technical into sequence points (though referencing them as it will be an important concept for the OP to learn before too long) – Assimilater Jul 14 '16 at 06:16
1

These lines will be throwing errors
because the variable 'x' you are sending as an argument does not exist in the scope of main

 int main()
 {
 ->  double x = towerHeight(x);
 ->  double y = secondsSinceDrop(x);

     printResult(x,y);

     return 0;
 }

Instead you could try something like this.

#include "stdafx.h"
#include <iostream>
#include "constant.h"
using namespace std;

//height of the tower
double towerHeight()
{
    double height;
    cout << "Enter a height for the tower" << '\n';
    cin >> height
    return height;
}

//the number of seconds since the ball has been dropped to determine the distance
double secondsSinceDrop()
{
    double seconds;
    cout << "How long has it been since you dropped the ball (Seconds): ";
    cin >> seconds;
    return seconds;
}

//finds how far off the ground the ball is 
double currentBallHeight(double x, double y)
{
    return y * constant::gravity - x;
}

//prints how far off the ground the ball is
void printResult(double x, double y)
{
    if (currentBallHeight(x, y) < 0)
        cout << "At " << y << " the ball is on the ground." << '\n';
    else
        cout << "At " << y << " the ball is at: " << currentBallHeight(x, y) << '\n';
}

int main()
{
    double height = towerHeight();
    double seconds = secondsSinceDrop();

    printResult(height, seconds);

    return 0;
}

Some tips that I would recommend

  • Declare your variables as much as relevant to you instead of using 'x/y/z'
  • There is no need to add the using namespace std; inside each function
  • 1
    C++ standard uses the word argument by itself to denote an actual argument and the word parameter by itself to denote a formal argument.. So you might wish to change `parameter` in your answer to `argument`. – sjsam Jul 14 '16 at 05:34
1

You seem to be struggling to connect the mental dots on what the computer is doing when you

  • declare variables with an initial value
  • define function parameters
  • return a value from a function

Not sure how this question will fair with the SO community as the preference is for Q/A that is succinct and reusable (maybe some editing can help) but for your benefit let me explain some of these concepts.


Let's start with a variable declaration

int x = 5;
int y = x;

When you define int x; it creates a space in RAM for an integer (4 bytes). Adding the = 5 initializes it immediately. It's important that the value on the right side of = (5 in this case) is known before the computer tries to make space for x.

It's fine to use values that aren't constant for variables like this (notice the second line in the example) but x has to be known before you declare y. In other words, this would obviously be a problem:

int y = x;
int x = 5;

For this same reason, the line: double x = towerHeight(x); is problematic because you're using x when you call towerHeight before ever defining x


When you define a function's parameters:

double towerHeight(double x) {

This tells the computer that you are going to copy the value from whatever called towerHeight to a new place in RAM and call it "x". This means that the value outside of the function doesn't get modified. Consider the following example:

double towerHeight(double x) {
    x = 5;
    std::cout << x << std::endl; // outputs 5
}
int main() {
    double x = 10;
    towerHeight(x);
    std::cout << x << std::endl; // outputs 10
    return 0;
}

Even though x was changed in towerHeight that was a "different copy of x" which also happened to be called the same name.


When you return a value from a function, in the same manner as passing a function argument, the return value is copied and used in places of the function call. Let's modify the previous example slightly:

double towerHeight(double x) {
    x = 5;
    return x;
}
int main() {
    double x = 10;
    x = towerHeight(x); // returns the value "5"
    std::cout << x << std::endl; // Outputs "5"
    return 0;
}

You can think of towerHeight(x) being replaced by "5" so the code would read x = 5;


Conclusion

You should try and use different variable names for

  • function arguments (the variables/values you pass to the function)
  • function parameters (what they are called inside the function)

to avoid this kind of confusion. Though there may be times where using the same name makes sense (i.e. passing by reference, which is another question). It's important for you to be aware of what's really going on.

Here is what you probably intend to do:

double towerHeight()
{
    double height;
    std::cout << "Enter a height for the tower" << std::endl;
    std::cin >> height;
    return height;
}
double secondsSinceDrop()
{
    double seconds;
    std::cout << "How long has it been since you dropped the ball (Seconds): ";
    std::cin >> seconds;
    return seconds;
}
double currentBallHeight(double y0, double t)
{
    return y0 - (constant::gravity * t * t / 2);
}
void printResult(double y0, double t)
{
    double currentHeight = currentBallHeight(y0, t);
    if (currentHeight < 0)
        std::cout << "At " << t << "s the ball is on the ground." << std::endl;
    else
        std::cout << "At " << t << "s the ball is at: " << currentHeight << std::endl;
}
int main()
{
    double y0 = towerHeight();
    double t = secondsSinceDrop();

    printResult(y0, t);

    return 0;
}

Summarizing what I've changed:

  • Renamed x to y0 since y(0)/h(0) is typically used for "initial height" in physics classes, and similarly y with t (though time would be an even better name).
  • Don't pass anything to towerHeight or secondsSinceDrop; you're not trying to give those functions something, you're trying to get something out of them.
  • Move the definition of x from a function parameter to a local variable defined in the function for towerHeight and secondsSinceDrop
  • Removed the duplicated call to currentBallHeight (no need to do the same math twice, it takes time to crunch numbers after all, however small in this case)
  • Rewrote for proper usage of std::cout and std::endl
  • Rewrote the currentBallHeight equation to match constant free-fall kinematics (y(t) = y(0) - 0.5g * t^2) as an added bonus (assuming constant::gravity > 0)

At some point it will be valuable for you to become aware of the more technical terminology and definitions for the concepts I've outlined here. Here are some recommended readings (just to get you started; keep learning, always):

Community
  • 1
  • 1
Assimilater
  • 944
  • 14
  • 33
0

Rewrite your function as following:

//height of the tower
double towerHeight()
{
        double x;
        using namespace std;
        cout << "Enter a height for the tower" << '\n';
        cin >> x;

        return x;
}

and in int main(){} rewrite following line:

double x = towerHeight();

I guess this will do but you can actually modify your double secondsSinceDrop(double x); function this way as it doesn't really need a double value as parameter.

Asif Rahaman
  • 775
  • 6
  • 10