You're pretty much correct about what's happening in the first example. You enter 10 20 30 40 into stdin, but it only takes the first number, 10, as input and stores it into numbers. The rest is left stuck in stdin and the program exits.
With proper indentation, I believe your code in the second example will be far clearer.
#include <iostream>
int main()
{
    int n = 0;
    while (std::cin >> n)
        std::cout << n << ' ';
}
Basically, this program works in a pretty weird way. In the first run of the while loop, let's say you input 1 2 3. Visualizing it, stdin would look like this:
1 2 3
Now, it has to take a number from this. So it takes 1 and then finds a space, so it stops. Now that 1 is in n, it prints 1 followed by a space. After the first run of the loop, stdin looks like this:
2 3
In the second run of the loop, it doesn't actually prompt you for more input because stdin is not empty. So it'll just take input from what's already there. It sees 2 at the beginning, takes that and stops at the next space, and puts it into n. n is then printed, followed by a space. stdin now looks like this:
3
Same thing happens with 3. It takes 3 and puts it into n which is printed, and this time stdin has been cleared. After this, std::cin takes no more input and returns false in the last check of the loop as it has hit eof. So to hopefully make things a bit clearer, after unrolling the loop, your program looks like this:
#include <iostream>
int main()
{
    int n = 0;
    std::cin >> n;         // Here you input "1 2 3", 1 is taken leaving "2 3" in stdin
    std::cout << n << ' '; // "1 " printed
    std::cin >> n;         // 2 is taken from stdin, leaving "3"
    std::cout << n << ' '; // "2 " printed
    std::cin >> n;         // 3 is taken from stdin, nothing left
    std::cout << n << ' '; // "3 " printed
}