essentially I'm writing a short script. The easiest way to look at is that it's for a game with a resource collection. ResGain is the resources gained, and BonusGain is the chance to earn an extra resource. I am getting Identifier not found errors for the ResGain and Bonus Gain functions, but I have declared the ResGain and BonusGain functions before main. Any ideas why?
#include <iostream>
#include <cstdlib>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
float ResGain(float u, int r) //calc Base resource Gain
{
float lapout;
lapout = r * u;
return (lapout);
}
char BonusGain(int b) //Determines if a bonus material would be produced.
{
char bonus;
int rng;
rng = rand() % 100 + 1;
if (rng <= b)
bonus = 1;
return(bonus);
}
int main()
{
float l;
l = ResGain(1.1,70);
cout << "You have earned" << l << "Lapis";
if (BonusGain(3)==1)
cout << "You have also earned a bonus material";
system("pause");
return 0;
}
Most probably the identifier not found is system() which is not part of the standard library. You should locate the Windows-specific header where it is declared.
Related
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <random>
#include <map>
#include <math.h>
#include <cstring>
using namespace std;
class MathClass {
private:
size_t current_capacity;
double* logfact;
bool inited = false;
MathClass() {
current_capacity = 0;
logfact = new double[1];
logfact[0] = 0;
}
void calculateLogFact(int n) {
if (current_capacity >= n) return;
double* newLogfact = new double[n+1];
for (int i=0; i<=current_capacity; i++) newLogfact[i] = logfact[i];
for (int i=current_capacity+1; i<=n; i++) newLogfact[i] = newLogfact[i-1] + log(double(i));
delete[] logfact;
logfact = newLogfact;
}
double factorial(int n) {
cout << "n = " << n << "\n";
calculateLogFact(n);
for (int i=0; i<=n; i++) cout << int64_t(round(exp(logfact[i]))) << " ";
cout << "\n";
return exp(logfact[n]);
}
public:
static double factorial2n(int n) {
static MathClass singleton;
return singleton.factorial(2*n);
}
};
int main(int argc, char** argv)
{
cout << MathClass::factorial2n(10) << "\n";
return 0;
}
My library need to use an expensive function that needs to be initialized once before use (to pre-calculate some expensive values so that we don't have to calculate them every time). Currently, I use the singleton method above for this.
However, there are 2 problems:
Multi-threading: this will cause race conditions if 2 different threads call this function.
People don't like singleton
Other problems that I'm not aware of
What other design can I use to solve this problem? Pre-computing values is a must since this function needs to be fast.
I agree with comments: Why hide the fact that MathClass caches results from the user? I, as a potential user, see no real benefit, rather potential confusion. If I want to reuse previously cached results stored in an instance I can do that. You need not wrap the whole class in a singleton for me to enable that. Also there is no need to manually manage a dynamic array when you can use std::vector.
In short: The alternative to using a singleton is to not use a singleton.
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <random>
#include <map>
#include <math.h>
#include <cstring>
using namespace std;
class MathClass {
private:
size_t current_capacity;
std::vector<double> logfact;
bool inited = false;
void calculateLogFact(int n) {
if (logfact.size() >= n) return;
auto old_size= logfact.size();
logfact.resize(n);
for (int i=old_size; i<n; i++) logfact.push_back(logfact.back() + log(double(i)));
}
double factorial(int n) {
cout << "n = " << n << "\n";
calculateLogFact(n);
for (int i=0; i<=n; i++) cout << int64_t(round(exp(logfact[i]))) << " ";
cout << "\n";
return exp(logfact[n]);
}
public:
MathClass() {
logfact.push_back(0);
}
double factorial2n(int n) {
return factorial(2*n);
}
};
void foo(MathClass& mc) { // some function using previously calculated results
std::cout << mc.factorial2n(2);
}
int main(int argc, char** argv)
{
MathClass mc;
cout << mc.factorial2n(10) << "\n";
foo(mc);
}
I am not sure if the maths is correct, I didn't bother to check. Also inited and most of the includes seem to be unused.
Concerning "Multi-threading: this will cause race conditions if 2 different threads call this function." I would also not bother too much to bake the thread-safety into the type itself. When I want to use it single-threaded I do not need thread-safety, and I don't want to pay for it. When I want to use it multi-threaded, I can do that by using my own std::mutex to protect access to the mc instance.
PS: Frankly, I think the whole issue is caused by a misconception. Your MathClass is not a "function only" class. It is a class with state and member functions, just like any other class too. The "misconception" is to hide the state from the user and pretend that there is no state when in fact there is state. When using this class I would want to be in conctrol what results I can query because they are already cached and which results need to be computed first. In other words, I would provide more access to the class state, rather than less.
So here's my code at the moment:
#include <iostream>
using namespace std;
int main() {
string x = "_one";
int sound_one = 7;
int sound_two = 8;
cout << ("sound") + x;
}
However when I run the code, it outputs 'sound_one' instead of '7'. How do I get it to output the variable sound_one instead of just 'sound_one'? Also, I need it so I can change x to different things (eg '_two') so it will then output sound_two instead. Any help would be greatly appreciated.
C++ is not a reflective language in the sense that you can acquire a variable name at runtime (variable names are normally compiled out of the program). You can use std::map though to achieve your immediate aim:
#include <iostream>
#include <string>
#include <map>
int main() {
using std::literals::string_literals::operator""s;
std::string x = "_one";
std::map<std::string, int> data;
data["sound_one"] = 7;
data["sound_two"] = 8;
std::cout << data["sound"s + x];
}
Note the notation "sound"s: the suffixed s denotes a std::string user defined literal.
You can't a variable from a string in this way. A work around is to use if/switch statements until the variable name is matched and then print it:
if(x == "_one") {
cout << sound_one;
}
else if(x == "_two") {
cout << sound_two;
}
else {
cout << "no match";
}
You can't do that in C++. You can use a map as shown in another answer, but I feel like what you really need is an array:
#include <format>
#include <iostream>
int main()
{
int data[] { 7, 8 };
std::cout << std::format("data[{}] = {}\n", 0, data[0]);
}
Arrays are usually better for such simple ordered sequences.
I am new to c++. Doing it for the past 9 months or so and didn't learn it by the books. I always learnt whatever I just tried to accomplish. This might have ended in me doing some sloppy codes, so I am happy if you guys would suggest advices for a more proper code, but mainly solve the issue at hand.
What my code does: It's supposed to create a structure that makes it easy for me find and use radii in two dimensions x[-50;50] y[-50;50] but only for integers. My declared structure for this task is indexed by "sqared radius" (max: 5000) and filled with:
an index (for later use of the array "radidx")
the amount of positions with the same radius
its true radius (sqrt)
the x and y position of each coordinate
Just so you know what's going on in my code.
Now the problem goes like this: If I declare the array "radidx" before the structure declaration I end up with my solution. But if I declare it after the structure, I get a segmentation error because entries in the structure seem to go terribly wrong.
As far as I know and a friend confirmed this. The order of declarations on top of my code - long before any of these declarations is used - shouldn't make a difference, so this must be because some sloppy coding of myself. I would like to improve on this in order to avoid similar issues in future codes and when putting this code here into use. Neither of us could figure out where and what went wrong.
#include <cstdlib>
#include <string>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <fstream>
#include <cmath>
#include <ctime>
#include <chrono>
#include <list>
#include <random>
using namespace std;
// int radidx[1030] = {0}; // Here it does work.
struct radii { int idx; int a=0; double r; int x[32]; int y[32]; };
radii radius[5000];
int radidx[1030] = {0}; // Here it doesn't work.
void rad_corr_init() {
int count [5001];
for (int i=0;i<5001;i++) count[i]=0;
/// Helper Function
/// count amount of positions with the same radius
for (int i=-50;i<51;i++)
for (int j=-50;j<51;j++)
count[i*i+j*j]++;
/// sort collected radii and exclude radii that don't exist so one can run a for-loop of an radius interval
int ik=0;
for (int i=1;i<5001;i++)
if(count[i]) {radidx[ik]=i; ik++;}
for (int i=-50;i<51;i++) // This is put here for testing
for (int j=-50;j<51;j++) { // This is put here for testing
int il = i*i+j*j; // This is put here for testing
radius[il].a=0; // This is put here for testing
} // This is put here for testing
/// Create Radius Structure
for (int i=-50;i<51;i++)
for (int j=-50;j<51;j++) {
int il = i*i+j*j;
int im = radius[il].a;
if (!radius[il].a) radius[il].r = sqrt(il);
radius[il].x[im] = i;
radius[il].y[im] = j;
radius[il].a++;
}
for (int i=0;i<1030;i++) {printf("%d\t%d\n",i,radidx[i]) /* This is put here for testing */ ;radius[radidx[i]].idx = i;}
}
int main() {
FILE * result = fopen( "result.txt", "w" );
rad_corr_init();
for (int i=0;i<1030;i++) {
int in = radidx[i];
int io = radius[in].a;
for (int j=0;j<io;j++) {
cout << i << '\t' << in << '\t' << radius[in].r << '\t' << j << '\t' << radius[in].x[j] << '\t' << radius[in].y[j] << endl;
fprintf(result, "%d\t%d\t%d\t%d\t%f\t%d\t%d\n", i, radius[in].idx, in, radius[in].r, j, radius[in].x[j], radius[in].y[j]);
}
}
// system("pause");
return 0;
}
I used the following commands for compiling (in case this is part of the issue):
g++ radius.cpp -std=c++11 -o ~[some name]/Desktop/run.out;time ~[some name]/Desktop/run.out
g++ -O4 radius.cpp -std=c++11 -o ~[some name]/Desktop/run.out;time ~[some name]/Desktop/run.out
Thank you guys for your help.
You have 5001 entries for count, but only 5000 for radius. When you access radius[50*50+50*50] (=radius[5000]) you exceed the bounds of the array and overwrite whatever is in memory after radius.
The solution is to change the declaration to radii radius[5001].
So I am new to c++, coming from C#. This is giving me several errors when compiling, which all seem to relate to this object declaration. Anyone able to show me the right way to do this?
I get an undeclared identifier where i declare tri(sideLength).
I have used this as a reference for object declaration, but it doesn't seem to be helping me.
Thanks.
#include <iostream> // Provides cout
#include <iomanip> // Provides setw function for setting output width
#include <cstdlib> // Provides EXIT_SUCCESS
#include <cassert> // Provides assert function
#include <stdexcept>
#include <math.h>
using namespace std; // Allows all standard library items to be used
void setup_cout_fractions(int fraction_digits)
// Precondition: fraction_digits is not negative.
// Postcondition: All double or float numbers printed to cout will now be
// rounded to the specified digits on the right of the decimal.
{
assert(fraction_digits > 0);
cout.precision(fraction_digits);
cout.setf(ios::fixed, ios::floatfield);
if (fraction_digits == 0)
cout.unsetf(ios::showpoint);
else
cout.setf(ios::showpoint);
}
int main()
{
const int MAX_SIDE_LENGTH = 6;
const int INITIAL_LENGTH = 1;
const int DIGITS = 4;
const int ARRAY_SIZE = 6;
// Set up the output for fractions and print the table headings.
setup_cout_fractions(DIGITS);
// Each iteration of the loop prints one line of the table.
for (int sideLength = 0; sideLength < MAX_SIDE_LENGTH; sideLength += 1)
{
EquilateralTriangle tri(sideLength);
//Square sq(sideLength);
//Pentagon_Reg pent(sideLength);
//Hexagon_Reg hex(sideLength);
//Heptagon_Reg hept(sideLength);
//Octagon_Reg octa(sideLength);
cout << "Type: " << tri.Name() << "has area: " << tri.Area() << " with SideLength = " << sideLength;
}
return EXIT_SUCCESS;
}
//Template
class GeometricFigure
{
public:
GeometricFigure() { }
double SideLength;
virtual double Area() { return 0; };
virtual char* Name() { return ""; };
};
class EquilateralTriangle : public GeometricFigure {
public:
EquilateralTriangle(double sideLength)
{
SideLength = sideLength;
}
char* Name() { return "Equilateral Triangle"; }
double Area() { return (sqrt(3) / 2 * pow(SideLength, 2)); }
};
In C++, the compiler reads your code from top-to-bottom, once. This is a holdover from when early C compilers only had a few kilobytes of memory to work with - C was designed so that a compiler would only need to look at a little bit of the code at a time.
Because of this, things must have been declared or defined as necessary, before you try to use them.
Move both classes somewhere before main. GeometricFigure must be before EquilateralTriangle, and EquilateralTriangle must be before main.
You would need to "declare" or tell the compiler, where to look for the EquilateralTriangle and GeometricFigure, "before" you use it first. you might want to take a look at the similar discussion at - C# declarations vs definitions
A problem set for people learning C++ is
Write a short program to simulate a ball being dropped off of a tower. To start, the user should be asked for the initial height of the tower in meters. Assume normal gravity (9.8 m/s2), and that the ball has no initial velocity. Have the program output the height of the ball above the ground after 0, 1, 2, 3, 4, and 5 seconds. The ball should not go underneath the ground (height 0).
Before starting C++ I had a reasonable, but primarily self taught, knowledge of Java. So looking at the problem it seems like it ought to be split into
input class
output class
calculations class
Physical constants class (recommended by the question setter)
controller ('main') class
The input class would ask the user for a starting height, which would be passed to the controller. The controller would give this and a number of seconds (5) to the calculations class, which would create an array of results and return this to the controller. The controller would hand the array of results to the output class that would print them to the console.
I will put the actual code at the bottom, but it's possibly not needed.
You can probably already see the problem, attempting to return an array. I'm not asking how to get round that problem, there is a workaround here and here. I'm asking, is the problem a result of bad design? Should my program be structured differently, for performance, maintenance or style reasons, such that I would not be attempting to return an array like object?
Here is the code (which works apart from trying to return arrays);
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;
}
And finally a couple of headers;
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_ */
I would say that you're over-engineering a big solution to a little problem, but to answer your specific question:
Should my program be structured differently, for performance, maintenance or style reasons, such that I would not be attempting to return an array like object?
Returning an array-like object is fine. But that doesn't mean returning an array, nor does it mean allocating raw memory with new.
And it's not restricted to return values either. When you're starting out with C++, it's probably best to just forget that it has built-in arrays at all. Most of the time, you should be using either std::vector or std::array (or another linear collection such as std::deque).
Built-in arrays should normally be viewed as a special-purpose item, included primarily for compatibility with C, not for everyday use.
It may, however, be worth considering writing your computation in the same style as the algorithms in the standard library. This would mean writing the code to receive an iterator to a destination, and writing its output to wherever that iterator designates.
I'd probably package the height and time together as a set of input parameters, and have a function that generates output based on those:
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;
}
}
This works somewhat more clearly along with the rest of the standard library:
std::vector<double> results;
calc_pos(inputs, std::back_inserter(results));
You can go a few steps further if you like--the standard library has quite a bit to help with a great deal of this. Your calc_pos does little more than invoke another function repeatedly with successive values for the time. You could (for example) use std::iota to generate the successive times, then use std::transform to generate outputs:
std::vector<int> times(6);
std::iota(times.begin(), times.end(), 0);
std::vector<double> distances;
std::transform(times.begin(), times.end(), compute_distance);
This computes the distances as the distance dropped after a given period of time rather than the height above the ground, but given an initial height, computing the difference between the two is quite trivial:
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); });
At least for now, this doesn't attempt to calculate the ball bouncing when it hits the ground--it just assumes the ball immediately stops when it hits the ground.
You should get rid of self-allocated double * and use std::vector<double> instead. It's not difficult to learn and a basic step in modern C++
This 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;
}