Order of incrementing and dereferencing pointer in C++

前端 未结 3 779
既然无缘
既然无缘 2021-01-14 10:06

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



        
相关标签:
3条回答
  • 2021-01-14 10:21

    This expression

    T min_value = *begin++; 
    

    can be imagined the following way

    auto temp = begin;
    T min_value = *temp;
    ++begin;
    

    According to the C++ Standard (5.2.6 Increment and decrement)

    1 The value of a postfix ++ expression is the value of its operand. [ Note: the value obtained is a copy of the original value —end note ] ...The value computation of the ++ expression is sequenced before the modification of the operand object.

    In general case the function definitions are wrong because the range specified by begin and end can be empty and begin can point beyond a valid range. In this case you may neither increase begin nor dereference it.

    So it would be more correctly to write for example the following way

    T * min( T* begin, T* end ) 
    {
        T *min_value = begin;
    
        if ( begin != end )
        {
            while( ++begin != end )
            { 
                if( *begin < *min_value ) min_value = begin; 
            } 
        }
    
        return min_value; 
    } 
    

    In this case the call of the function will look like

    cout << "min of arr[] is : " << *min(arr, arr + 5) << endl;
                                   ^^^
    
    0 讨论(0)
  • 2021-01-14 10:25

    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.

    0 讨论(0)
  • 2021-01-14 10:42

    You should not confuse the return value of an operator and the priority.

    The first is dealing with what the operator returns, the second deals with when something happens.

    So if you have:

    T min_value = *begin++;
    

    Here is how it works:

    1. operator++ - it increments the pointer, but returns the pointer that was there originally.
    2. operator* - dereferences the pointer returned previously, returns T that it pointed to.
    3. operator= stores left-hand side into right-hand side, returns right-hand side.

    You don't use the last return value, but you theoretically could.

    Note here, that in #2 you use the return from #1, rather than accessing the pointer again.

    0 讨论(0)
提交回复
热议问题