I recently used a for statement for a code that calculates the distance of an object every second after dropping it from a given height. The for function is shown below.
My question is, how come if I took out the line "s = s + 1" - then made the "s" in the for function into "++s"/"s++" (Yes I know the difference between ++s and s++) - how come the new value for "s" wont go into the "Distance(s)" function until the 3rd time? The first cout will show 's' as '0' as it should. But the next run through it'll show 's' as '1' as it should, but wont enter that '1' into the distance function - Instead, the Distance function receives a '0' ! Only the third time around will The Distance function receive a '1' - and then the whole equation will continue like that - Being one off the whole time. Sorry - This is hard to explain. To see this happening for yourself, just comment out "s = s + 1" and put "++s" in the for function and compare results. Easy to compare if you always input "100" for your tower height.
Here's how I Think for functions work - Correct me if I'm wrong:
for (Variable Being Changed; Condition; How It Changes;)
Here is the specific 'for' function I'm talking about. While using "s = s + 1" - the function works perfectly. Using "++s" instead will lead to 'i' falling one calculation short of 's'.
1 2 3 4 5 6
for (h; i > 0.000; s)
{ //Precision Set At 6 Since It Shows Less Math Error
std::cout << "At " << s << " Seconds, The Ball Is At: " << std::setprecision(6) << i << " Meters." << '\n';
s = s + 1;
i = h - Distance(s);
}
#include "stdafx.h"
#include <iostream>
#include "constants.h" /* Remove This Header And Just Switch "constants::gravity" with 9.8 To Compile. */
#include <cmath>
#include <iomanip>
#include <string>
// Sorry For Not Initializing - But So Far Visual Studio Handles Them As If They're '0' Until Otherwise Assigned.
char g;
double h;
double d;
double a;
double p;
int t;
std::string o;
char i;
double Distance(int s)
{
a = pow(s,2) / 2;
return a * constants::gravity; // gravity = 9.8
}
int main()
{
std::cout << "One Meter Is 3.28084 Feet. One Foot Is .3048 Meters." << '\n'
<< "Type In 'C' Followed By The Number Of Feet To Convert Feet To Meters." << '\n' << "-----------------------------------------------------------------------" <<std::endl;
Begin:
int s{}; // To Reset 'S' Value After Each Run Through.
std::cout << '\n' << "The Height In Meters Of The Dark Tower: ";
std::cin >> g;
if (g == 'C' || g == 'c')
{
o = std::cin.peek();
if (o.find('\n') != std::string::npos) // In Case They Type In 'C'/'c' With No Number To Convert.
{
std::cout << '\n' << "Must Input A Number To Convert." << '\n' << std::endl;
std::cin.clear();
std::cin.ignore(10000, '\n');
goto Begin;
}
if (o.find(' ') != std::string::npos) // In Case They Type In 'C'/'c' With No Number To Convert.
{
std::cout << '\n' << "Must Input A Number To Convert. Do Not Add Spaces." << '\n' << std::endl;
std::cin.clear();
std::cin.ignore(10000, '\n');
goto Begin;
}
double x;
std::cin >> x;
if (std::cin.fail()) // If They Type In C Followed By A Non-Number.
{
std::cout << '\n' << "Input Only A Number For Conversion." << '\n' << std::endl;
std::cin.clear();
std::cin.ignore(10000, '\n');
goto Begin;
}
h = x / 3.28084;
std::cout << x << " Feet Is " << h << " Meters." << std::endl;
}
else
{
std::cin.putback(g);
std::cin >> h;
}
if (std::cin.fail())
{
std::cout << '\n' << "Input Only A Number." << '\n' << std::endl;
std::cin.clear();
std::cin.ignore(10000, '\n');
goto Begin;
}
double i = h;
for (h; i > 0.000; s)
{ //Precision Set At 6 Since It Shows Less Math Error
std::cout << "At " << s << " Seconds, The Ball Is At: " << std::setprecision(6) << i << " Meters." << '\n';
s = s + 1;
i = h - Distance(s);
}
if (i <= 0.00) // Was Coding Quickly - this may not need to be an if function - But Better Safe Than Sorry.
{
std::cout << "At " << s << " Seconds, The Ball Is On The Ground." << '\n';
}
std::cout << '\n';
std::cin.clear();
std::cin.ignore(10000, '\n');
goto Begin;
}
s would be incremented at two different positions.
As you have it at the moment, s and i are "in sync"; that is, the height reflects the current value of s.
If you put s++ in the for statement, then s will be incremented AFTER changing height. So, when you come to write std::cout << "At " << s << " Seconds, The Ball Is At: " << std::setprecision(6) << i << " Meters." << '\n';
your s and i will not correspond to the same instance in time.
To put s and i back in sync you could write your for() loop as (note the order of statements):
1 2 3 4 5 6
for ( ; i > 0.0; s++)
{
i = h - Distance(s);
if ( i < 0.0 ) break;
std::cout << "At " << s << " Seconds, The Ball Is At: " << std::setprecision(6) << i << " Meters." << '\n';
}
// A
int s = 0;
double i = h;
for ( ; i > 0.000 ; )
{
std::cout << "At " << s << " sec, At: " << i << " meters.\n";
s = s + 1;
i = h - Distance(s);
}
// B
int s = 0;
double i = h;
for ( ; i > 0.000 ; )
{
std::cout << "At " << s << " sec, At: " << i << " meters.\n";
++s;
i = h - Distance(s);
}
// C
int s = 0;
double i = h;
for ( ; i > 0.000; ++s )
{
std::cout << "At " << s << " sec, At: " << i << " meters.\n";
i = h - Distance(s);
}
I was wondering about the difference between A and C. But it's fine now - Thanks Keskiverto.
Thanks a lot lastchance - I can't believe I didn't see that earlier - Lack of sleep must be getting to me. I wrote the code in a way where when 's' changes, the next line will change 'i' accordingly - So it didn't even cross my mind that the order of operations inside the for statement was causing the 's' and 'i' to be out of sync when changing 's' through the for function. Thanks again !