我应该尝试返回数组,还是有更好的解决方案? P>学习C++的一个问题是
写一个简短的程序来模拟一个球从塔上掉下来。首先,应向用户询问塔的初始高度(以米为单位)。假设正常重力(9.8 m/s2),且球没有初始速度。让程序在0、1、2、3、4和5秒后输出球离地高度。球不应进入地面以下(高度0) <> P>开始C++之前,我有一个合理的,但主要是自学的java知识。因此,从这个问题来看,它似乎应该被分成几个部分我应该尝试返回数组,还是有更好的解决方案? P>学习C++的一个问题是,c++,arrays,C++,Arrays,写一个简短的程序来模拟一个球从塔上掉下来。首先,应向用户询问塔的初始高度(以米为单位)。假设正常重力(9.8 m/s2),且球没有初始速度。让程序在0、1、2、3、4和5秒后输出球离地高度。球不应进入地面以下(高度0) P>开始C++之前,我有一个合理的,但主要是自学的java知识。因此,从这个问题来看,它似乎应该被分成几个部分 输入类 输出类 计算类 物理常数类(由提问者推荐) 控制器('main')类 输入类将要求用户输入起始高度,该高度将传递给控制器。控制器将给calculation
- 输入类
- 输出类
- 计算类
- 物理常数类(由提问者推荐)
- 控制器('main')类
/*
* 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;
}
常数.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_ */
您应该摆脱自分配的
double*
,改用std::vector
。这并不难学,也是现代C++的一个基本步骤。我想说的是,你在为一个小问题设计一个大的解决方案,但要回答你的具体问题:
出于性能、维护或样式的原因,我的程序是否应该采用不同的结构,这样我就不会试图返回类似数组的对象
返回类似数组的对象是可以的。但这并不意味着返回数组,也不意味着使用new
分配原始内存
而且它也不限于返回值。当你开始用C++时,最好忘记它有内置数组。大多数情况下,您应该使用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;
}
}
这将计算距离
作为给定时间段后下降的距离,而不是地面以上的高度,但给定初始高度,计算两者之间的差异非常简单:
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); });
双初始高度=5;
标准:向量高度;
std::transform(距离.begin(),距离.end(),
标准:背面插入器(高度),
[=](双v){返回最大值(初始高度-v,0);};
至少现在,这并不试图计算球落地时的反弹——它只是假设球落地时立即停止。这就是我解决问题的方法:
#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;
}
#包括
#包括
#包括
使用std::cin;
使用std::cout;
使用std::endl;
使用std::sqrt;
使用std::fixed;
使用std::setprecision;
使用std::max;
使用std::setw;
静态常数双g=9.81;
类计算器{
公众:
计算器(双inh):h(inh)
{
}
void DoWork()常量{
双tmax=sqrt(h/(g/2));
对于(double t=0.0;我投票结束这个问题,因为这个问题不属于主题。@TatanLlama啊,我认为你是对的……另外,不要使用int numResults=sizeof(results)/sizeof(results[0]);
,这对指针不起作用。@Jamey D谢谢,很高兴知道。我想你已经把解决方案复杂化了。在我看来,问题是要为()提供一个简单的
循环相关的数学运算。我不认为有任何理由将每个结果存储在内存中的时间超过打印它所需的时间。我很感激这个问题不属于这里,但这绝对避免了回答它…@Jekowl:您当前的calculateResults()
函数返回指向本地临时数组的指针,但根本不起作用。返回std::vector
将避免该问题。@blastfurny谢谢,这解释了为什么marom的解决方案可以解决该问题。问题实际上是关于我的设计是否糟糕。谢谢,这是一个非常有用的答案。我注意到您曾经使用过使用名称空间std;
这是应该避免的吗?@Jekowl:是的,我通常会避免使用它。使用名称空间foo;
语句通常是有用的,但是std
名称空间足够大,并且包含的内容足够多,我可以避免让所有这些名称直接可见——有太多的cha你写的东西意外碰撞的后果。
/*
* Contains physical constants relevant to simulation.
* SI units
*/
#ifndef CONSTANTS_H_
#define CONSTANTS_H_
namespace constants
{
const double gravity(9.81);
}
#endif /* CONSTANTS_H_ */
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));
std::vector<int> times(6);
std::iota(times.begin(), times.end(), 0);
std::vector<double> distances;
std::transform(times.begin(), times.end(), compute_distance);
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); });
#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;
}