3

I'm trying to make a use of a relay module, I want a clear way to configure and control my relay module I've defined the struct and filled it with some info about id, pin number, title, and relay state I can't loop with for in the array of controls, because I can't get the sizeof the array right

typedef struct{
  int id;
  int pin;
  String title;
  bool state;
}  SwitchControl;

SwitchControl controls[2] = {
  {1, 22, "Switch 01", 1},
  {2, 23, "Switch 02", 0},
};


for(int i=0; i<sizeof(controls) - 1; i++){
}

thanks

5
  • 1
    This is really a C++ question more than anything. In case you're wondering the Arduino source preprocessing has no effect on this.
    – timemage
    Nov 14 '20 at 13:52
  • 3
    Try (sizeof(controls)/sizeof(controls[0]) or better (sizeof(controls)/sizeof(SwitchControl)) Nov 14 '20 at 14:20
  • for (const auto &e: controls) { or std::size if you happen to have that. <shrugs> still seems like a C++ question really.
    – timemage
    Nov 14 '20 at 14:22
  • I would code a const right above, eg. MAX_CONTROL, which keeps later code clean and (I think) faster, as C++ doesn't have to calc anything each time it's used.
    – dandavis
    Nov 14 '20 at 20:26
  • @dandavis, A constant expression like one involving the division of the result of two sizeof operators will be evaluated at compile time in pretty much any compiler. Or at least those made after about 1992 or so.
    – timemage
    Nov 14 '20 at 20:36
3

To make it generic, you simply divide the sizeof the array by the sizeof the type:

for(int i=0; i<sizeof(controls)/sizeof(SwitchControl); i++){
}

Then you can later change the items if the array, or the structure and the code will be the same.

2

A more generic way (usable in future cases) is:

// number of items in an array
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))

Now you can use ARRAY_SIZE (the_array) in your code like this:

for(int i=0; i<ARRAY_SIZE (controls); i++){
}

The above works in C as well as C++.


The more C++ way of doing it is to use a template like this:

// number of items in an array
template< typename T, size_t N > size_t ArraySize (T (&) [N]){ return N; }

Now ArraySize(the_array) returns the number of elements in the array:

for(int i=0; i< ArraySize (controls); i++){
}

The "Arduino language" is C++ with some initial pre-processing. For all intents and purposes any tutorial on C++ will help you with Arduino programming (except that the Standard Template Library (STL) is not included by default).


I don't know why you were subtracting 1 in your posted code. Did you not want to iterate through the whole array?

0

sizeof(controls) returns the size, in bytes, of the entire object which is not what you want. You want the number of elements.

I'll point out that since you're statically allocating this as:

SwitchControl controls[2]

The size you are looking for is always going to be 2. So just use 2 in your for loop like:

for(int i=0; i<2; i++)

2
  • 1
    The number of elements is 2 for now. But the point in using sizeof() with statical allocation is, that you can easily add more elements to the array, without changing all the for loops in your code. It is highly probable, that the shown code of the OP is just a test code, and that the final code might have more elements and the number of elements might change between different iterations of the code. While your suggestion works, it is not a good tip to do so.
    – chrisl
    Nov 14 '20 at 18:36
  • I think you're reading a lot more into this question that is currently there. Yes, you are correct but sometimes you need to walk before you can run.
    – jwh20
    Nov 14 '20 at 20:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.