Iterators
std::vector<int> v{5, 2, 8, 2, 9}; stores five ints side by side in one block of memory. We will walk along this row without using indexes at all. The tool for that is an iterator.
v.begin() gives an iterator to the first element. v.end() gives one to the position just past the last: a place, not an element. Together b and e describe a range [b, e): b is included, e is not.
An iterator marks one position, like a bookmark. *it reads the element it marks: here 5. ++it moves it on to the next element, the 2. For a vector it behaves like a pointer into the row.
The loop starts it at b, adds *it to sum and moves on with ++it. It stops as soon as it == e, so it never reads the end. Sum: 5 + 2 + 8 + 2 + 9 = 26.
Algorithms
std::find(b, e, 8) gets only the two iterators, never the vector. It walks from b, compares each element with 8 and stops at the first match. It returns an iterator to it: p marks v[2].
Look for 7 instead. std::find compares all five elements, finds no 7, and returns e, the end. So always check p != e before you use *p: reading *e is undefined behaviour.
std::sort(b, e) puts the values in order, in place: 2, 2, 5, 8, 9. It moves values, not iterators. p still marks the third place, which now holds 5, not 8. sort needs iterators that can jump, like a vector's.
std::count(b, e, 2) walks the same range and counts the elements equal to 2: n = 2. Every standard algorithm works like this: give it a range, get an answer or a changed range.
Run it, and a trap
Line 13 prints sum and n: 26 2. Line 14 prints *p. p still points at the third place, and after the sort that place holds 5.
Now call v.push_back(1). If the block is full, the vector moves every element to a new, bigger block. b, e and p still point at the old place: they are invalidated. Using them is undefined behaviour, so get fresh ones.
What happens
;; step 1/10 · vector
5 std::vector<int> v{5, 2, 8, 2, 9};
v[0] v[1] v[2] v[3] v[4]
5 2 8 2 9
one block of memory, no gaps
v.size() == 5
end() is a position, not an element: reading *v.end() is undefined behaviour. Because ranges are half-open, an empty range is simply b == e, and the number of elements is e - b. Each algorithm says which iterators it needs. std::find only reads forward, so it works on every container. std::sort needs random-access iterators, so std::sort on a std::list does not compile; a list has its own l.sort().