Should I try to return an array or is there a better solution?

Set problem for people learning C ++,

Write a short program to simulate a ball falling out of a tower. To start, the user needs to ask the initial tower height in meters. Suppose that the normal weight (9.8 m / s2), and that the ball does not have an initial speed. Ask the program to display the height of the ball above the ground after 0, 1, 2, 3, 4, and 5 seconds. The ball must not be underground (height 0).

Before starting C ++, I had a reasonable, but above all self-learning, knowledge of Java. Therefore, looking at the problem, it seems that it should be divided into

  • input class
  • output class
  • class of calculations
  • Class of physical constants (recommended by the question installer)
  • controller class ('main')

The input class asks the user for the initial height, which will be passed to the controller. The controller would give this and a few seconds (5) to the computation class, which would create an array of results and return it to the controller. The controller will pass an array of results to the output class, which will print them to the console.

I will put the actual code below, but it may not be needed.

You can probably already see the problem while trying to return an array. I do not ask how to get around this problem, it exists here and here . I ask, is the problem a result of poor design ? Should my program be structured differently for performance, maintenance, or style reasons so that I don't try to return an array similar to an object?

( , );

main.cpp

/*
 * Just the main class, call other classes and passes variables around
 */
#include <iostream>
#include "dropSim.h"
using namespace std;

int main()
{
    double height = getHeight();
    int seconds = 5;
    double* results = calculateResults(height, seconds);
    outputResults(results);
    return 0;
}

getHeight.cpp

/*
 *  Asks the user for a height from which to start the experiment
 *  SI units
 */
#include <iostream>
using namespace std;

double getHeight()
{
    cout << "What height should the experiment start at; ";
    double height;
    cin >> height;
    return height;
}

calculateResults.cpp

/*
 * given the initial height and the physical constants, the position of the ball
 * is calculated at integer number seconds, beginning at 0
 */

#include "constants.h"
#include <cmath>
#include <iostream>
using namespace std;

double getPosition(double height, double time);

double* calculateResults(double height, int seconds)
{

    double positions[seconds + 1];
    for(int t = 0; t < seconds + 1; t++)
    {
        positions[t] = getPosition(height, t);
    }
    return positions;
}

double getPosition(double height, double time)
{
    double position = height - 0.5*constants::gravity*pow(static_cast<double>(time), 2);
    if( position < 0) position = 0;
    //Commented code is for testing
    //cout << position << endl;
    return position;
}

outputResults.cpp

/*
 *      Takes the array of results and prints them in an appropriate format
 */


#include <iostream>
#include <string>
#include <sstream>

using namespace std;

void outputResults(double* results){
    string outputText = "";
    //The commented code is to test the output method
    //Which is working
    //double results1[] = {1,2,3,4,5};
    //int numResults = sizeof(results1)/sizeof(results1[0]);
    int numResults = sizeof(results)/sizeof(results[0]);
    //cout << numResults; //= 0 ... Oh
    for(int t = 0; t < numResults; t++)
    {
        ostringstream line;
        line << "After " << t << " seconds the height of the object is " << results[t] << "\r";
        outputText.append(line.str());

    }
    cout << outputText;
}

, , ; dropSim.h

/*
 * dropSim.h
 */

#ifndef DROPSIM_H_
#define DROPSIM_H_

double getHeight();

double* calculateResults(double height, int seconds);

void outputResults(double* results);

#endif /* DROPSIM_H_ */

constants.h

/*
 *      Contains physical constants relevant to simulation.
 *      SI units
 */

#ifndef CONSTANTS_H_
#define CONSTANTS_H_

namespace constants
{
    const double gravity(9.81);
}

#endif /* CONSTANTS_H_ */
+4
3

, , :

-, , , , ?

, , . , new.

. ++, , . std::vector, std::array ( , ​​ std::deque).

, C, .

, , , , . , .

, :

struct params {
    double height;
    int seconds;
};

template <class OutIt>
void calc_pos(params const &p, OutIt output) { 
    for (int i=0; i<p.seconds; i++) {
        *output = get_position(p.height, i);
        ++output;
    }
}

:

std::vector<double> results;

calc_pos(inputs, std::back_inserter(results));

, - , . calc_pos , . () std::iota , std::transform :

std::vector<int> times(6);

std::iota(times.begin(), times.end(), 0);

std::vector<double> distances;

std::transform(times.begin(), times.end(), compute_distance);

distances , , , :

double initial_height = 5;

std::vector<double> heights;

std::transform(distances.begin(), distances.end(), 
    std::back_inserter(heights),
    [=](double v) { return max(initial_height-v, 0); });

, , , - , , .

+7

double * std::vector<double>. ++

+3

Here is how I would solve the problem:

#include <cmath>
#include <iostream>
#include <iomanip>

using std::cin;
using std::cout;
using std::endl;
using std::sqrt;
using std::fixed;
using std::setprecision;
using std::max;
using std::setw;

static const double g = 9.81;

class Calculator {
public:
   Calculator(double inh) : h(inh)
   {
   }

   void DoWork() const {
      double tmax = sqrt(h / ( g / 2));
      for (double t=0.0; t<tmax; t+=1.0) {
         GenerateOutput(t);
      }
      GenerateOutput(tmax);
   }
private:
   void GenerateOutput(double t) const {
      double x = g * t * t / 2;
      double hremaining = max(h - x, 0.0);     
      cout << fixed << setprecision(2) << setw(10) << t;
      cout << setw(10) << hremaining << endl;
   }

   double h;
};

int main() {
   double h(0.0);

   cout << "Enter height in meters: ";
   cin >> h;
   if (h > 0.0) {
      const Calculator calc(h);
      calc.DoWork();  
   } else {
      return 1;
   }

   return 0;
}
+1
source

All Articles