0

In C code, I'm stuck right here, trying to assign some values to a structure array. I just learned C++ and don't know much on how pointers work. Here is the code as for now:

typedef struct Weather {
    float temperature;
    float wind;
    float humidity;
    float precipitation;
} Weather;

const int NUMDATA = 1440;
Weather weather[NUMDATA];



float* generateRandom(float max, float min) {

    static float array[NUMDATA];
    
    for (int i=0; i<NUMDATA; i++) {
        array[i] = rand() / (float) RAND_MAX * (max - min) + min;
    }    
    
    return array;
}


void readWeather() {
    
    weather.temperature = generateRandom(40,20);
    weather.wind = generateRandom(20,0);
    weather.humidity = generateRandom(100,0);
    weather.precipitation = generateRandom(20,0);
    
}

I just run the readWeather() function in the main function and it outputs an error for each line in readWeather() saying that

main.cpp:44:13: error: request for member ‘wind’ in ‘weather’, which is of non-class type ‘Weather [1440]

  • The variable `array` will be *shared* between all calls to `generateRandom`. The function will not create new instances of the array. Use `std::vector` or `std::array` to return instead. – Some programmer dude Sep 15 '22 at 18:51
  • 2
    C and C++ are two different languages. The error message indicates that you are really compiling it as C++, but the code looks more like C, not C++. Don't mix the two languages. Although a lot of C code is also valid C++, most C code would not count as good C++ style. Actually it is a weird mix, because although it looks like C with all that `typedef` stuff, it is not actually valid C, because of the `const int` used as array size. – user17732522 Sep 15 '22 at 18:52
  • 1
    What is the variable `weather` *really*? Is it an instance of the `Weather` structure? Or it it something else? Similarly with e.g. `Weather::temperature`, what type is it really? Is it the same type that `generateRandom` returns? – Some programmer dude Sep 15 '22 at 18:54
  • 1
    And if you want to learn C++ properly, ***forget that you know C!*** Invest in [some good C++ books](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list/388282#388282) and learn from scratch. There are really very little that knowing basic C syntax will bring to learning C++, they really are two very different languages. – Some programmer dude Sep 15 '22 at 18:56
  • That trick of returning a `static` local variable isn't good practice. This won't work well in a mutithreaded environment. Just use a for ranged for loop and all the values of one object in the loop body: `for(Weather& w : weather) { w.temperature = ...; ... }` – fabian Sep 15 '22 at 20:11
  • or use the ranges lib if you insist on going property by property: `template void generateRandom(Range&& r, float max, float min) { for(auto pos = r.begin(), end = r.end(); pos != end; ++pos) { *pos = std::rand() / (float)RAND_MAX * (max - min) + min; } }` `generateRandom(weather | std::views::transform([](Weather& w) -> float& { return w.temperature; }), 40, 20); generateRandom(weather | std::views::transform([](Weather& w) -> float& { return w.wind; }), 20, 0);` You'll btw usually see values mentioned in ascending order; it's quite confusing to see the max go first. – fabian Sep 15 '22 at 20:12

1 Answers1

0

Since you're manipulating arrays, not single elements, you need to somehow loop over them to do the assignment. You might do a for loop:

float* rnd = generateRandom(40, 20);
for (int i = 0; i < NUMDATA; ++i) {
    weather[i].temperature = rnd[i];
}
rnd = generateRandom(20, 0);
for (int i = 0; i < NUMDATA; ++i) {
    weather[i].wind = rnd[i];
}
// etc.

You might also use std::memcpy() as these are POD types (float types). However, to make it cleaner, it's better to use std::array<>, and/or to pass the reference to the array to be filled instead of returning a pointer to a function-local static. That'd look like this:

void generateRandom(float* array, float max, float min, size_t numData = NUMDATA) { 
    for (int i=0; i<numData; i++) {
        array[i] = rand() / (float) RAND_MAX * (max - min) + min;
    }
}

void readWeather() {
    for (int i = 0; i < NUMDATA; ++i) {
        generateRandom(weather[i].temperature, 40, 20);
        generateRandom(weather[i].wind, 20, 0);
        // ...
    }
}
lorro
  • 10,687
  • 23
  • 36