Read-Only Access
Our normalize
function modified the array to normalize the data, but suppose we wanted to write a max_value
function that just reads the array to work out its maximum value. Here's the code.
float max_value(float* firstValPtr, float* pastEndPtr) {
float maxval = *firstValPtr;
for (float* p = firstValPtr; p < pastEndPtr; ++p) {
if (*p > maxval) {
maxval = *p;
}
}
return maxval;
}
Do you have any concerns?
The Solution: const
I think I know how to fix it! Declare it as a
const float*
.Just like we did with references.
That's right. It's the same idea.
If we know our function won't modify the array and we want to make it clear in the interface, we can write it as:
float max_value(const float* firstValPtr, const float* pastEndPtr) {
float maxval = *firstValPtr;
for (float* p = firstValPtr; p < pastEndPtr; ++p) {
if (*p > maxval) {
maxval = *p;
}
}
return maxval;
}
How do I read
const float* firstValPtr
in English?You read it from right-to-left as usual:
firstValPtr
is a pointer to afloat
that'sconst
(i.e., read-only).And it's the
float
that'sconst
, not the pointer.Yes.
Can we have the pointer itself be
const
instead?Yes. And if you remember we read types from right-to-left, you might be able to figure out how.
Where we put the const
matters:
const float* firstValPtr
says thefloat
that the pointer points to can't change—it's a pointer toconst float
.float* const firstValPtr
says the pointer itself can't change.const float* const firstValPtr
says both—that the pointer itself can't change, and thefloat
it points to can't change.
Working on Part of An Array
Hay, wait a minute. Could I use this kind of begin…end style to work out the
max_value
of just part of an array? Likemaxval(vals+2, maxval+5)
?Totally. Since we specify the start pointer and the past-the-end pointer, we can choose.
The range style for passing array data makes it easy to work with only part of an array.
Empty Ranges
What if I did
maxval(vals,vals)
?That would be an empty range. The starting point is already past the end.
I think I've found a bug in our
max_value
function, then. The code saysfloat maxval = *firstValPtr;
Doesn't that mean that we'll read the “past-the-end” point? Are we allowed to do that?
You have indeed found a bug. Our code was designed for arrays with at least one element.
And no, if some position is supposed to be “past-the-end”, you shouldn't read it.
You could fix the code to start out with -∞, like this:
float maxval = -std::numeric_limits<float>::infinity;
Yes, sure, if we knew how to do that kind of thing. Or we could just document that the function doesn't work on an empty range. After all, it's fair to say that if there isn't any data, it doesn't have a maximum value and so you shouldn't try to ask what it is.
But it is kinda cool to know we can represent ∞ in C++!
Okay, that's some good progress so far! Let's head up to the parent page to see how far we've come and maybe take a break.
(When logged in, completion status appears here.)