That's right. The headers aren't sent the instant header() is called: they're collected up and then sent all together (either immediately before output or, if there wasn't any output, at the end of the script). Buffering can also have an effect; there may be a gap between the output being generated and the output actually being sent (flush() will override this behaviour at least at PHP's level). It's a matter of trying to fill tcp packets efficiently.
And since all http responses have headers, it doesn't matter if header() or any other header-generating function is called or not: there will be headers and they will need to be sent at some point.