0

I am bit new to C++. I am trying to use struct to keep my data better organised.

in the following code I am trying to modify a struct member. all members are named using an int.

I have two problems:

My counder currentParticleCount wont increment after adding to the struct. there seem to be errors in the way I am using the counter i in the for loop to reference the stuct data...

As I said I am quite new to C++ I probably dont know the correct terms for what I am trying to achieve, and am not finding any real answers online.

int currentParticleCount = 0;
 
struct particle
{
 int velocity;
 int trajectory;
 int currentPosition[2] = {0, 0};
 int mass;
};

void createParticle()
{
  struct particle currentParticleCount = {
    random(1, 10),
    random(0, 360),
    {random(1, MAX_SCREEN_HEIGHT), random(1, MAX_SCREEN_WIDTH)},
    random(1, 10),
  };
  currentParticleCount++;
}

void runParticles()
{
  for (int i = 0; i < currentParticleCount; i++)
  {
    particle.i.currentPosition[0] = particle.i.currentPosition[0] + ((particle.i.velocity) * cos(particle.i.trajectory));

    particle.i.currentPosition[0] = particle.i.currentPosition[0] + ((particle.i.velocity) * sin(particle.i.trajectory));
  }

}

I get the following errors:

_particle: In function 'void createParticle()':

144:25: warning: no 'operator++(int)' declared for postfix '++', trying prefix operator instead [-fpermissive]
     currentParticleCount++;
                         ^

_particle:144: error: no match for 'operator++' (operand type is 'particle')

_particle: In function 'void runParticles()':

_particle:151: error: expected unqualified-id before '.' token
     particle.i.currentPosition[0] = particle.i.currentPosition[0] + ((particle.i.velocity) * cos(particle.i.trajectory));
             ^

_particle:153: error: expected unqualified-id before '.' token
     particle.i.currentPosition[0] = particle.i.currentPosition[0] + ((particle.i.velocity) * sin(particle.i.trajectory));
             ^

no match for 'operator++' (operand type is 'particle')
Useless
  • 64,155
  • 6
  • 88
  • 132
Nick
  • 908
  • 12
  • 29
  • 4
    `struct particle currentParticleCount` hides `int currentParticleCount = 0;` – Jarod42 May 19 '21 at 13:22
  • 2
    ot: better don't use random numbers for testing and debugging. In the early stage reproducibility is very imporant. (i mean first you need to get it to compile, but then you want to be able to rerun a test when it fails) – 463035818_is_not_an_ai May 19 '21 at 13:24
  • 1
    Also: `particle.i` should probably be something like `particles[i]` (assuming you create a `std::vector particles` somewhere) – 0x5453 May 19 '21 at 13:24
  • @jarod42 so how do i instigate a new entry into the struct using my counter to name it? should I move the counter increment outside of that function? – Nick May 19 '21 at 13:28
  • 1
    You probably want a `std::vector` (so you can even get rid of `currentParticleCount`). – Jarod42 May 19 '21 at 13:31
  • Regarding `int currentParticleCount = 0`: using gobal variables inside functions is bad, and causes bugs such as the one pointed out by @Jarod42, pass the count to the function as a parameter instead. Regarding `particle.i` should be `particle[i]`. `particle` is a type, you're using it as a value. Declare an array of particles if you know how many you need (or an `std::vector` if you don't) `createparticles` is not doing what you think it is doing... – Eli Algranti May 19 '21 at 13:34

2 Answers2

2

Your code has a few issues; I'll try my best to address all of them:

void createParticle()
{
  struct particle currentParticleCount = {
    random(1, 10),
    random(0, 360),
    {random(1, MAX_SCREEN_HEIGHT), random(1, MAX_SCREEN_WIDTH)},
    random(1, 10),
  };
  currentParticleCount++;
}
  1. You don't need the struct keyword here - particle <name> {...} is sufficient.
  2. You declare a particle instance named currentParticleCount, which shadows the global int currentParticleCount. Choose a different name for your particle.
  3. You create a particle on the stack, but then you never do anything with it. It will be deleted at the end of the function scope. Based on some of the surrounding code, it looks like you meant to save the particle off somewhere - I'd recommend a std::vector.
void runParticles()
{
  for (int i = 0; i < currentParticleCount; i++)
  {
    particle.i.currentPosition[0] = particle.i.currentPosition[0] + ((particle.i.velocity) * cos(particle.i.trajectory));

    particle.i.currentPosition[0] = particle.i.currentPosition[0] + ((particle.i.velocity) * sin(particle.i.trajectory));
  }
}
  1. particle.i is not valid syntax. Presumably this is meant to run for all known particles, so assuming your container is called particles, you would use particles[i] to access a single particle in the container.
  2. You update currentPosition[0] twice in a row - I'm guessing one of those should be currentPosition[1]. Even better, you could make a position struct with x and y members to be even more clear than [0] and [1].
  3. In general, a = a + b can be shortened to a += b.

Other things:

  1. If you follow my suggestion above and use a std::vector<particle>, you won't even need currentParticleCount - it would simply become particles.size(). Additionally, if you do that, you can use the easier "range-based for loop" syntax, e.g.:
for (particle& p : particles) {
  p.currentPosition[0] = ...
}
  1. Global variables should almost always be avoided. Instead you should be passing things around as function parameters and returning values from your functions.
0x5453
  • 12,753
  • 1
  • 32
  • 61
1

Here's a version that will run. It is far from a proper C++ version, it doesn't use the standard library or any of the newer C++ standards niceties but will hopefully show you where you're going wrong:

#include <stdlib.h>
#include <time.h> 
#include <math.h>

using namespace std;

// Declare the struct
struct particle
{
 int velocity;
 int trajectory;
 int currentPosition[2]; // another struct such as struct point {int x; int y;} would be better here
 int mass;
};

const int PARTICLE_COUNT = 100; // A constant with the number of particles
const int MAX_SCREEN_HEIGHT = 1080;
const int MAX_SCREEN_WIDTH = 1920;

int random(int from, int to) {
    return rand() % (to - from) + from; 
}

// Gets a reference to the particle and initializes it
void initParticle(particle& currentParticle) {
    currentParticle.velocity = random(1, 10);
    currentParticle.trajectory = random(0, 360);
    currentParticle.currentPosition[0] = random(1, MAX_SCREEN_HEIGHT);
    currentParticle.currentPosition[1] = random(1, MAX_SCREEN_WIDTH);
    currentParticle.mass = random(1, 10);
}

// pass the array as reference
void runParticles(particle (&particles)[PARTICLE_COUNT]) {
    for (int i=0; i<PARTICLE_COUNT; ++i) {
        particles[i].currentPosition[0] = particles[i].currentPosition[0] + ((particles[i].velocity) * cos(particles[i].trajectory));
    }
}

// pass a pointer to the first element in the array
// it's good style to pass the size as well in this case
void otherRunParticles(particle* particles, int size) {
    for (int i=0; i<size; ++i) {
        particles[i].currentPosition[0] = particles[i].currentPosition[0] + ((particles[i].velocity) * cos(particles[i].trajectory));
    }
}

int main()
{
    srand(time(NULL));
    
    // declare an array of `struct particle` called `particles`
    particle particles[PARTICLE_COUNT];
    
    // initialize the array
    for (int i=0; i<PARTICLE_COUNT; ++i) {
        initParticle(particles[i]);
    }

    // Now you can do whatever you want with the particles
    runParticles(particles);
    
    otherRunParticles(particles, PARTICLE_COUNT);

    return 0;
}
Jarod42
  • 203,559
  • 14
  • 181
  • 302
Eli Algranti
  • 8,707
  • 2
  • 42
  • 50
  • `if you declare like so typedef struct` that’s true for C, but not C++ – alagner May 19 '21 at 15:15
  • @Eli-Algrani - thankyou. I have learnt a great deal from this. thanks for your help – Nick May 19 '21 at 15:27
  • @alagner You can use typedef in C++ and it'll behave the same as in C. You are correct that it is not needed, in C++ `particle` is also type without the typedef unless hidden by a different declaration. https://stackoverflow.com/questions/612328/difference-between-struct-and-typedef-struct-in-c – Eli Algranti May 19 '21 at 21:10