Output can be buffered or unbuffered. With buffered output, the implementation saves up all the output until it's convenient to write it to disk (or wherever). This is nice and efficient, but if the program crashes some output will very likely be lost. The implementation has to write unbuffered output to disk as it occurs, which can slow things down with lots of disk writes, but unless there's a program crash while it's being written it will be written to disk.
There's no real functional difference between standard output and standard error; they're just two different output streams that can be redirected separately. The Unix philosophy of chaining tools together is that standard output will have the appropriate output to go into the input of the next tool, and this pretty much requires that there be a separate stream for error messages.
So, cout
writes to standard output, and is buffered. Use this for normal output. cerr
writes to the standard error stream, and is unbuffered. Use this for error messages. clog
writes to the standard error stream, but is buffered. This is useful for execution logging, as it doesn't interfere with standard output, but is efficient (at the cost that the end of the log is likely to be lost if the program crashes).