Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.1k views
in Technique[技术] by (71.8m points)

arrays - Order of incrementing and dereferencing pointer in C++

I tutor students in C++, and recently came across a problem involving pointer arithmetic with array names. The main thing I'm confused about is the statement

T min_value = *begin++; 

Cplusplus tells me that the ++ operator has higher precedence than the * dereference operator, so I assume that begin is first incremented and then dereferenced. Also, this site confirms that when you pass the name of an array to a function, it gets turned into a pointer to the address of the first element, element [0]. However, when I run the code below in Visual Studio, it looks like min_value is set to be 1.5 at the beginning, which seems to contradict what I think the order of operations are.

I think it should be:

  1. increment the begin pointer to the [1] element (2nd in the array)
  2. dereference the pointer value
  3. set min_value to be equal to the 2nd element in the array.

However, my experiment seems to indicate that instead something different is happening:

  1. dereference pointer value
  2. set min_value equal to 1st element of array
  3. increment pointer to next element

Can someone clarify this?

// Problem #3: Please write the implementation of min() function and max() function..

#include <iostream> 
using namespace std; 
template<typename T> 

T min(T* begin, T* end) 
{ 
        T min_value = *begin++; 
        while(begin != end) // You can use for-loop too. 
        { 
                if( *begin < min_value) 
                        min_value = *begin; 
                begin++; 
        } 
        return min_value; 
} 
template<typename T> 
T max(T* begin, T* end) 
{ 
        T max_value = *begin++; 
        while(begin != end) 
        { 
                if( *begin > max_value) 
                        max_value = *begin; 
                begin++; 
        } 
        return max_value; 
} 
int main() 
{ 
        double arr[] = {    1.5, 4.5, 3.5, 2.5, 5.5 }; 
        int values[] = {    1, 2, 3, 4, -1, 5 }; 
        cout << "min of arr[] is : " << min(arr, arr + 5) << endl; 
        cout << "min of values[] is : " << min(values, values + 6) << endl; 
        cout << "max of arr[] is : " << max(arr, arr + 5) << endl; 
        cout << "max of values[] is : " << max(values, values + 6) << endl; 
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Precedence is only a rule for how the code should be parsed. ++ comes first, and * comes second. But when the code is executed, you have to consider what the operators actually do.

In your case, the following happens:

  1. A copy of begin is made.
  2. The original is incremented.
  3. The copy is returned.
  4. The copy is dereferenced.
  5. The copy is assigned to min_value.

That's just how the post-increment operator works, and it's also how you write the operator when you overload it for your own types:

T operator++(int)
{
    T copy = *this;
    ++(*this);
    return copy;
}

Actually, in the case of the built-in post-increment operator, incrementation does not necessarily have to be step 2. It could also happen at a later point, as long as the observable behaviour is the same. For example, nothing stops the compiler from incrementing the original value after it has returned the copy. You could not perform such a thing in your own, overloaded operator, of course.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...