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* firstValPtrin English?
You read it from right-to-left as usual:
firstValPtris a pointer to afloatthat'sconst(i.e., read-only).
And it's the
floatthat'sconst, not the pointer.
Yes.
Can we have the pointer itself be
constinstead?
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* firstValPtrsays thefloatthat the pointer points to can't change—it's a pointer toconst float.float* const firstValPtrsays the pointer itself can't change.const float* const firstValPtrsays both—that the pointer itself can't change, and thefloatit 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_valueof 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_valuefunction, 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.)