That 3 in your first example is definitely a magic number that should be either dynamically calculated from the number of elements being averaged, or defined as a const NUMBER_ELEMENTS_AVERAGED.
In the general case, of course you would use arrays (static or dynamic) and some kind of "size" attribute.
But this is just 3 values in an expression and using a constant could actually be bad. Let's be a bit more practical.
int lightness(int r, int g, int b) { return (r+g+b)/3; }
Simple and straightforward
int lightness(int r, int g, int b) {
const int NUMBER_ELEMENTS_AVERAGED = 3;
return (r+g+b)/NUMBER_ELEMENTS_AVERAGED;
}
Ok, I guess, but I think verbose for no good reason. But not as bad as the seemingly "cleaner"
const int NUMBER_OF_COLOR_COMPONENTS = 3;
int lightness(int r, int g, int b) {
return (r+g+b)/NUMBER_OF_COLOR_COMPONENTS;
}
Imagine that you want want to add a color component, for example to support transparency (alpha). So you set NUMBER_OF_COLOR_COMPONENTS = 4, and then, your "lightness" function breaks, the simple (r+g+b)/3 would have stayed correct. That happened because didn't get the real meaning of that "3". Even if semantically, at the time you written that code, it is the number of color components, in reality, it is the number of terms in the expression. There is r, g, b: 3 terms, so 3. Who cares how many color components there are?
Side note: I know it is the wrong formula for lightness, that's just an example.
If you name it `NUMBER_ELEMENTS_AVERAGED`, then when you add a new element to average, you will miss the fact that you also need to modify that value :)
You either have them on a list and calculate it dynamically based on the size, or have it as a magic number.