Traversing an array with a pointer to the array I was thinking about how to traverse an array without an int iterator, and I'm curious if my answer is good/bad.
The first for loop simply populates each element of the array.
The second for loop traverses through the array. The int pointer, curr, initially points to the first address of the array then goes on to momentarily hold the address of each element of the array. The int pointer, ptrLastElement, contains the address of the last element of the array arr.
The check condition is essentially the difference of the address contained in ptrLastElement and the address contained in curr. If the difference is less than 0, then we've ran out of elements to display.
My main questions are:

Would this idea ever be useful?
Is this a terrible idea?
Did I do anything incredibly stupid?
How can I improve this and/or make it more generic?

main.cpp
#include &lt;iostream&gt;

int main()
{
    const size_t SIZE = 10;
    int arr[SIZE];
    int * ptrLastElement = arr + (SIZE-1);
    
    // Populate the array, arr, using int iterator
    for (int i = 0; i &lt; SIZE; ++i)
    {
        arr[i] = i;
    }
    
    // Traversing arr using a pointer
    for (int * curr = arr; (ptrLastElement - curr) &gt;= 0 ; ++curr)
    {
        std::cout &lt;&lt; curr &lt;&lt; &quot;\t&quot; &lt;&lt; *curr &lt;&lt; std::endl;
    }
    
    return 0;
}
It's not terrible as it stands, but the code could be improved.  Here are some ideas on how to do so.

Minimize work within the loop

If we redefine ptrLastElement to something like this:

const int *end = &amp;arr[SIZE];


Since the pointer starts from the beginning of the array, the for loop could instead look like this:

for (int * curr = arr; curr != end; ++curr)


This matches the use of real iterators in the standard library by having the end of the array be one beyond the last element.  

However, modern C++ rarely uses pointers, so I would probably neither use nor advise anyone else to use such a construct.  There's little benefit and the use of pointers can lead to difficult-to-find errors.

Don't use std::endl if '\n' will do

Using std::endl emits a \n and flushes the stream.  Unless you really need the stream flushed, you can improve the performance of the code by simply emitting '\n' instead of using the potentially more computationally costly std::endl.

Omit return 0

When a C or C++ program reaches the end of main the compiler will automatically generate code to return 0, so there is no need to put return 0; explicitly at the end of main.  

Note: when I make this suggestion, it's almost invariably followed by one of two kinds of comments:  "I didn't know that." or "That's bad advice!"  My rationale is that it's safe and useful to rely on compiler behavior explicitly supported by the standard.  For C, since C99; see ISO/IEC 9899:1999 section 5.1.2.2.3:


  [...] a return from the initial call to the main function is equivalent to calling the exit function with the value returned by the main function as its argument; reaching the } that terminates the main function returns a value of 0.


For C++, since the first standard in 1998; see ISO/IEC 14882:1998 section 3.6.1:


  If control reaches the end of main without encountering a return statement, the effect is that of executing return 0;


All versions of both standards since then (C99 and C++98) have maintained the same idea.  We rely on automatically generated member functions in C++, and few people write explicit return; statements at the end of a void function.  Reasons against omitting seem to boil down to "it looks weird".  If, like me, you're curious about the rationale for the change to the C standard read this question.  Also note that in the early 1990s this was considered "sloppy practice" because it was undefined behavior (although widely supported) at the time.  

So I advocate omitting it; others disagree (often vehemently!)  In any case, if you encounter code that omits it, you'll know that it's explicitly supported by the standard and you'll know what it means.